codeforces 864F Cities Excursions
正解:$tarjan$。
因为点数只有$3000$,而询问很多,所以我们可以把起点相同的询问一起搞。
注意到如果没有环,那么我们每次直接走字典序最小的那条边就行了。
如果有环那么就是不合法的情况,要输出$-1$,判环我们可以使用$tarjan$算法。每次先把点$x$的$low$设为$inf$,然后如果之前经过的路径可以到达$x$,那么就肯定有环。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define M (400005) 6 #define N (3005) 7 8 using namespace std; 9 10 struct data{ int i,u,v,k; }q[M]; 11 12 int ans[M],dfn[N],low[N],st[N],inst[N],Q,n,m,cnt,top; 13 14 vector<int> g[N],c[N]; 15 16 il int gi(){ 17 RG int x=0,q=1; RG char ch=getchar(); 18 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 19 if (ch=='-') q=-1,ch=getchar(); 20 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 21 return q*x; 22 } 23 24 il int cmp(const data &a,const data &b){ return a.u<b.u; } 25 26 il void dfs(RG int x,RG int fg){ 27 dfn[x]=++cnt,low[x]=1<<30,inst[x]=1,st[++top]=x; 28 if (fg){ 29 for (RG int i=0,sz=c[x].size();i<sz;++i) 30 if (q[c[x][i]].k<=top) ans[q[c[x][i]].i]=st[q[c[x][i]].k]; 31 } 32 for (RG int i=0,v,sz=g[x].size();i<sz;++i){ 33 v=g[x][i]; 34 if (!dfn[v]) dfs(v,fg && dfn[x]<low[x]),low[x]=min(low[x],low[v]); 35 else if (inst[v]) low[x]=min(low[x],dfn[v]); 36 } 37 inst[x]=0,--top; return; 38 } 39 40 int main(){ 41 #ifndef ONLINE_JUDGE 42 freopen("city.in","r",stdin); 43 freopen("city.out","w",stdout); 44 #endif 45 n=gi(),m=gi(),Q=gi(); 46 for (RG int i=1,u,v;i<=m;++i) u=gi(),v=gi(),g[u].push_back(v); 47 for (RG int i=1;i<=n;++i) sort(g[i].begin(),g[i].end()); 48 for (RG int i=1;i<=Q;++i) q[i].i=i,q[i].u=gi(),q[i].v=gi(),q[i].k=gi(); 49 sort(q+1,q+Q+1,cmp),memset(ans,-1,sizeof(ans)); 50 for (RG int i=1;i<=Q;++i){ 51 c[q[i].v].push_back(i); if (q[i].u==q[i+1].u) continue; 52 memset(dfn,0,sizeof(dfn)),memset(low,0,sizeof(low)); 53 cnt=top=0,dfs(q[i].u,1); for (RG int j=1;j<=n;++j) c[j].clear(); 54 } 55 for (RG int i=1;i<=Q;++i) printf("%d\n",ans[i]); return 0; 56 }