tarjan求缩点,然后算缩点之后的图是不是一字链。
判断是不是一字链很简单,直接dfs求出一条最长边。
看最长边是不是等于缩点之后的数目即可。
#include <iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> using namespace std; #define maxm 10000 #define maxn 1100 #define eps 0.000001 #define zero(x) ((fabs(x)<eps?0:x)) #define INF 99999999 struct gra { struct list { int u,v,next; } edge[maxm]; int head[maxn]; int vis[maxn]; int num; int n; int id[maxn]; int od[maxn]; int shuyu[maxn]; int nums; int viss[maxn]; int dnf[maxn],low[maxn],times,instack[maxn]; stack<int>qq; void init() { memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(shuyu,0,sizeof(shuyu)); memset(dnf,0,sizeof(dnf)); memset(low,0,sizeof(low)); memset(instack,0,sizeof(instack)); memset(viss,0,sizeof(viss)); while(!qq.empty())qq.pop(); num=0; nums=1; times=1; } void add(int u,int v) { edge[num].u=u; edge[num].v=v; edge[num].next=head[u]; head[u]=num++; } void tarjan(int x) { dnf[x]=low[x]=times++; instack[x]=1; qq.push(x); for(int i=head[x]; i!=-1; i=edge[i].next) { int y=edge[i].v; if(!dnf[y]) { tarjan(y); low[x]=min(low[x],low[y]); } else if(instack[y]) { low[x]=min(low[x],dnf[y]); } } if(low[x]==dnf[x]) { int y=-1; while(x!=y) { y=qq.top(); shuyu[y]=nums; qq.pop(); instack[y]=0; } nums++; } } void start() { for(int i=1; i<=n; i++) { if(!dnf[i])tarjan(i); } } int dfs(int x,int p) { int mm=p; for(int i=head[x]; i!=-1; i=edge[i].next) { mm=max(mm,dfs(edge[i].v,p+1)); } return mm; } } G,g; int main() { int n,i,j,m,a,b,T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); G.init(); g.init(); G.n=n; for(i=1; i<=m; i++) { scanf("%d%d",&a,&b); G.add(a,b); } G.start(); g.n=G.nums; int nin,nout; nin=nout=0; for(i=1; i<=G.n; i++) { for(j=G.head[i]; j!=-1; j=G.edge[j].next) { int u=G.edge[j].u; int v=G.edge[j].v; if(G.shuyu[u]==G.shuyu[v])continue; G.id[G.shuyu[v]]++; G.od[G.shuyu[u]]++; // cout<<G.shuyu[u]<<" - "<<G.shuyu[v]<<endl; g.add(G.shuyu[u],G.shuyu[v]); } } for(i=1; i<G.nums; i++) { if(G.id[i]==0)nin++; if(G.od[i]==0)nout++; } if(nin>1||nout>1) { cout<<"No"<<endl; continue; } for(i=1; i<G.nums; i++) { if(G.id[i]==0)break; } // cout<<g.dfs(i,1)<<endl; if(g.dfs(i,1)==G.nums-1)cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }