题意:对任给的两个点x,y,是否一定有路,从x到y,或者从y到x,,,刚开始看错了,以为是赤裸裸的Tarjan,结果是或,不是且,,比较简单
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> using namespace std; const int N = 1009; const int M = 6009; const int INF = 0x3f3f3f3f; int n,m; struct LT{ int nex,to; } L[M]; int F[N],cnt; void add(int f,int t) { L[cnt].nex = F[f]; L[cnt].to = t; F[f] =cnt++; } void init() { scanf("%d%d",&n,&m); memset(F,0,sizeof(F)); cnt =1; int f,t; for(int i=0;i<m;i++) scanf("%d%d",&f,&t),add(f,t); } int dfn[N],low[N],post[N],col[N],color,ind; stack<int> S; void tarjan(int k) { dfn[k] = low[k] = ind++; post[k] = 1;S.push(k); for(int i=F[k];i;i=L[i].nex) { int to = L[i].to; if(!dfn[to]) { tarjan(to); low[k] = min(low[k],low[to]); }else if(post[to]&&dfn[to]<low[k]) { low[k] = dfn[to]; } } if(low[k]==dfn[k]) { int i;color++; for(i=S.top(),S.pop();i!=k;i=S.top(),S.pop()) { post[i] = 0,col[i] = color; } post[k] = 0;col[k] = color; } } struct node{ int nex,to; } tL[M]; int tF[N],tcnt; int in[N]; void tadd(int f,int t) { tL[tcnt].nex = tF[f]; tL[tcnt].to = t; tF[f] = tcnt++; } void solve() { memset(dfn,0,sizeof(dfn)); color = 0; ind = 1; for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); memset(tF,0,sizeof(tF)); memset(in,0,sizeof(in)); tcnt =1; for(int i=1;i<=n;i++) for(int j=F[i];j;j=L[j].nex) { int to = L[j].to; if(col[i]!=col[to]) { tadd(col[i],col[to]); } } memset(in,0,sizeof(in)); for(int i=1;i<tcnt;i++) in[tL[i].to]++; int ans =0,v=-1; for(int j=1;j<color;j++) {//for(int i=1;i<=color;i++) cout<<in[i]<<" ";cout<<endl; ans =0; for(int i=1;i<=color;i++) if(!in[i]) { ans++;in[i] = INF;v=i; } if(ans>1) { printf("No\n");return ; } for(int i=tF[v];i;i=tL[i].nex) { in[tL[i].to]--; } } printf("Yes\n"); } int main() { freopen("in.txt","r",stdin); int cas; scanf("%d",&cas); while(cas--) { init(); solve(); } return 0; }