제출 #1162946

#제출 시각아이디문제언어결과실행 시간메모리
1162946spongbTropical Garden (IOI11_garden)C++20
100 / 100
1679 ms29800 KiB
#include<bits/stdc++.h> #include "garden.h" #include "gardenlib.h" using namespace std; int cycle_len; vector<int> succ, color, dist, dist1, dist2; vector<bool> visited; vector<vector<int>> revGraph; int find_cycle_length(int node){ int slow = node; int fast = node; do { if(succ[fast] == -1 || succ[succ[fast]] == -1) return 1e9+1; slow = succ[slow]; fast = succ[succ[fast]]; } while(slow != fast); //cycle exists //now check if P is part of cycle bool inCycle = false; int temp = slow; int len = 0; do { if (temp == node) inCycle = true; len++; temp = succ[temp]; } while (temp != slow); return inCycle ? len : (1e9+1); } void dfs(int v, int d, vector<int> &dist, vector<vector<int>> &revGraph){ if(dist[v] != -1) return; dist[v] = d; for(int u: revGraph[v]){ dfs(u, d+1, dist, revGraph); } } void count_routes(int N, int M, int P, int ed[][2], int q, int qry[]) { vector<int> most_beautiful(N, -1); vector<int> second_most_beautiful(N, -1); for(int i = 0 ; i < M; i++){ //since edges are already given in decreasing order of beauty, you can choose the earlier one int u = ed[i][0]; int v = ed[i][1]; if(most_beautiful[u] == -1) most_beautiful[u] = v; else if(second_most_beautiful[u] == -1) second_most_beautiful[u] = v; //using if here would be a mistake it should be if else if(most_beautiful[v] == -1) most_beautiful[v] = u; else if(second_most_beautiful[v] == -1) second_most_beautiful[v] = u; } //for nodes with only since edge, they can choose the most_beautiful one again even if its used, so it becomes their second most beautiful edge too //this cant be applied for nodes with multiple edges when there is an alternative second edge, it should be chosen. this is why we used if/else if statements in above for loop //and not just use if and if directly without the need for this extra for loop. because then we'd be setting the best edge as the first best and also the second best which is wrong //for nodes with multiple options for(int i = 0; i < N; i++){ if(second_most_beautiful[i] == -1) second_most_beautiful[i] = most_beautiful[i]; } //now for each state(starting at each vertex), you exactly exactly one outgoing edge at each vertex //if you reached v using the its most_beautiful edge, then v should should second_most_beautiful edge to go next //say you used second_most_beautful[v] to reach w, and maybe that's w's most beautiful edge, so w should use its second most beautiful //so this is a functional graph //for every vertex v, you'll either reach v or v' (based on the path taken to reach v) //now v has exactly one outgoing edge //v' has exactly one outgoing edge //its a functional graph basically //build the outgoing edge for each vertex (v and v') succ.resize(2*N, -1); revGraph.assign(2 * N, vector<int>()); for(int i = 0; i < N; i++){ int f = most_beautiful[i]; int s = second_most_beautiful[i]; if(most_beautiful[f] == i){ succ[i] = f + N; } else succ[i] = f; if(most_beautiful[s] == i){ succ[i + N] = s + N; } else succ[i + N] = s; } //find cycle length int cycle_len1 = 1e9 + 1, cycle_len2 = 1e9 + 1; cycle_len1 = find_cycle_length(P); cycle_len2 = find_cycle_length(P + N); revGraph.resize(2*N); for(int i = 0; i < 2*N; i++){ if(succ[i] != -1) revGraph[succ[i]].push_back(i); } dist1.assign(2*N, -1); dfs(P, 0, dist1, revGraph); dist2.resize(2*N, -1); dfs(P+N, 0, dist2, revGraph); int ans = 0; for(int i = 0; i < q; i++){ int K = qry[i]; int ways = 0; for(int j = 0; j < N; j++){ if(dist1[j] == K) ways++; else if(cycle_len1 != 1e9+1 && dist1[j] != -1 && dist1[j] < K && ((K - dist1[j]) % cycle_len1 == 0)) ways++; if(dist2[j] == K) ways++; else if(cycle_len2 != 1e9+1 && dist2[j] != -1 && dist2[j] < K && ((K - dist2[j]) % cycle_len2 == 0)) ways++; } answer(ways); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...