开始填连通分量大坑。。
tarjan强连通分量求缩点重构图(终于知道tarjan缩点是什么意思了QWQ),出度为0的点若只有一个则输出其代表强连通分量的大小,否则无解。
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 50000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 struct edge{ 18 int t,v; 19 edge *next; 20 }e[NM],*h[NM],*o=e; 21 void add(int x,int y){ 22 o->t=y;o->next=h[x];h[x]=o;o++; 23 } 24 int n,m,ans,low[NM],d[NM],suc[NM],tot,cnt,_x,_y,out[NM]; 25 stack<int >s; 26 void dfs(int x){ 27 d[x]=low[x]=++tot;s.push(x); 28 link(x) 29 if(!d[j->t]){ 30 dfs(j->t); 31 low[x]=min(low[x],low[j->t]); 32 }else if(!suc[j->t]) 33 low[x]=min(low[x],low[j->t]); 34 if(low[x]==d[x]){ 35 int t;cnt++; 36 do{ 37 t=s.top();s.pop(); 38 suc[t]=cnt; 39 }while(x!=t); 40 } 41 } 42 int main(){ 43 // freopen("data.in","r",stdin); 44 n=read();m=read(); 45 inc(i,1,m){ 46 _x=read();_y=read(); 47 add(_x,_y); 48 } 49 inc(i,1,n) 50 if(!d[i])dfs(i); 51 inc(i,1,n) 52 link(i) 53 if(suc[j->t]!=suc[i])out[suc[i]]++; 54 inc(i,1,cnt) 55 if(!out[i]){ 56 if(ans){ 57 printf("-1\n"); 58 return 0; 59 }else ans=i; 60 } 61 cnt=0; 62 inc(i,1,n) 63 if(suc[i]==ans)cnt++; 64 printf("%d\n",cnt); 65 return 0; 66 }