codeforces 864 F
2017-09-27 20:54
302 查看
有向图,倍增。
思路:参考大佬的题解
倍增思想,比如求s到t的道路,那么先通过反向图dfs出所有可以到达t的节点。(相当于一棵树)如果s不在其中,输出-1.然后先用正向图的边把st数组初始化一下(用字典序最小的一个)。然后把st[t][0]置为n+1.其他剩余点都保持为0.然后在倍增完成后,如果st[ s ][ TOP ] ==n+1说明x最终可以到达t并且继续走到n+1.(2^TOP>3000).否则st[ s ][ TOP ] ==0说明s根本无法走到t。还有一种情况,st[ s ][ TOP ]!=0且!=n+1。那么就说明s进入了字典序循环中,无法走出。巧妙点就是这个把st[ t ][0]初始置为n+1。
学习了新的方法,对倍增又有了一个深刻的认识哇。
思路:参考大佬的题解
倍增思想,比如求s到t的道路,那么先通过反向图dfs出所有可以到达t的节点。(相当于一棵树)如果s不在其中,输出-1.然后先用正向图的边把st数组初始化一下(用字典序最小的一个)。然后把st[t][0]置为n+1.其他剩余点都保持为0.然后在倍增完成后,如果st[ s ][ TOP ] ==n+1说明x最终可以到达t并且继续走到n+1.(2^TOP>3000).否则st[ s ][ TOP ] ==0说明s根本无法走到t。还有一种情况,st[ s ][ TOP ]!=0且!=n+1。那么就说明s进入了字典序循环中,无法走出。巧妙点就是这个把st[ t ][0]初始置为n+1。
学习了新的方法,对倍增又有了一个深刻的认识哇。
#include<bits/stdc++.h> using namespace std; const int MAXN = 3000+5; int n,m,q; vector<int>head[MAXN],G[MAXN];//正反向图 int st[MAXN][13];//倍增数组 //询问 struct node { int s,k,id; node(int s,int k,int id) { this->s = s; this->k = k; this->id = id; } }; vector<node>ask[MAXN]; //dfs找到可以到达t的点 bool vis[MAXN]; void dfs(int u) { vis[u] = 1; for(int v : G[u])if(!vis[v])dfs(v); } //存答案 int ans[400005]; int main() { scanf("%d%d%d",&n,&m,&q); int u,v; while(m--) { scanf("%d%d",&u,&v); head[u].push_back(v); G[v].push_back(u); } for(int i = 1; i <= n; ++i)sort(head[i].begin(),head[i].end()); int s,t,k; for(int i = 0; i < q; ++i) { scanf("%d%d%d",&s,&t,&k); ask[t].push_back(node(s,k,i)); } for(int t = 1; t <= n; ++t) { if(ask[t].size() == 0)continue; fill(vis+1,vis+1+n,0); dfs(t); memset(st,0,sizeof st); st[n+1][0] = n+1; for(int u = 1; u <= n; ++u) { if(u == t)st[u][0] = n+1; else if(vis[u]) { for(int v : head[u]) { if(!vis[v])continue; st[u][0] = v; break; } } } for(int i = 1; i <= 12; ++i) for(int j = 1; j <= n+1; ++j)st[j][i] = st[st[j][i-1]][i-1]; //查询ask中的询问 for(node x : ask[t]) { int s = x.s; int k = x.k-1; int id = x.id; if(st[s][12] == n+1) { for(int i = 0; i <= 12; ++i) { if(k & (1<<i))s = st[s][i]; } if(s != n+1)ans[id] = s; else ans[id] = -1; } else ans[id] = -1; } } for(int i = 0; i < q; ++i) { printf("%d\n",ans[i]); } return 0; }
相关文章推荐
- Codeforces 864 C Bus
- Codeforces 864 D Make a Permutation!
- Codeforces 864D D. Make a Permutation!【思维+线段树+二分+这是一个煞笔做法】
- codeforces——contest 864 problemE
- codeforces contest 864 problemD
- CodeForces 864
- 【Codeforces 864 C. Bus】
- 【CodeForces - 864】 A B C【模拟】 D【贪心+优先队列】
- codeforces 954 D. Fight Against Traffic【BFS + 最短路】
- CodeForces - 698B Fix a Tree(并查集)
- Codeforces 845F Guards In The Storehouse
- Codeforces--366D--Dima and Trap Graph(并查集)
- codeforces 27E - Number With The Given Amount Of Divisors (数论 dfs)
- codeforces 8C - Looking for Order 状态DP
- Codeforces 534D - Handshakes (贪心 + 模拟)
- Codeforces 899D Shovel Sale
- CodeForces - 58B Coins(水题。。大水题)
- CodeForces - 417A Elimination (完全背包)
- CodeForces 19B Checkout Assistant
- Codeforces 716C C. Plus and Square Root