第一道强连通分量的题,,,泪牛满面啊,,,话说,看这个算法有4、5天了吧,今天终于写出来一道题,,纠结。几天写了一道题,,,这可怎么办???这道题就是先求出强连通分量的个数,如果强连通分量个数为1,则图是强连通图,输出n即可。否则的话,统计其中独立强连通分量的个数,所谓独立强连通分量,就是外面的点到不了该强连通分量。若独立强连通分量的个数为1,则输出出度为0的强连通分量所包含的点得个数,否则输出0.
题目:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 15106 | Accepted: 5990 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
#include <iostream> #include <string.h> #include <vector> #include <cstdio> using namespace std; const int N=10010; int dfn[N],in[N],out[N],belong[N]; int low[N],num[N]; vector<int> ss[N]; int stack[N],instack[N]; int top,index,cnt; void init(){ memset(dfn,0,sizeof(dfn)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(belong,0,sizeof(belong)); memset(low,0,sizeof(low)); memset(num,0,sizeof(num)); memset(ss,0,sizeof(ss)); memset(stack,0,sizeof(stack)); memset(instack,0,sizeof(instack)); } int min(int x,int y){ if(x<y) return x; return y; } void targin(int x){ int j; low[x]=dfn[x]=++index; stack[++top]=x; instack[x]=1; for(int i=0;i<ss[x].size();++i){ j=ss[x][i]; if(dfn[j]==0) {targin(j);low[x]=min(low[x],low[j]);} else if(instack[j]){ low[x]=min(low[x],dfn[j]); } } if(dfn[x]==low[x]){ cnt++; do{ j=stack[top--]; belong[j]=cnt; num[cnt]++; instack[j]=0; }while(x!=j); } } int main(){ //freopen("2.txt","r",stdin); int n,m; while(~scanf("%d%d",&n,&m)){ init(); top=index=cnt=0; int x,y; while(m--){ scanf("%d%d",&x,&y); ss[x].push_back(y); } for(int i=1;i<=n;++i){ if(dfn[i]==0) targin(i); } /*for(int i=1;i<=n;++i) printf("%d ",low[i]); printf("\n");*/ for(int i=1;i<=n;++i){ for(int j=0;j<ss[i].size();++j){ x=belong[i]; y=belong[ss[i][j]]; if(x!=y){ out[x]=1; in[y]=1; } } } //printf("cnt==%d\n",cnt); if(cnt==1) { printf("%d\n",n); continue; } int sum=0,count=0,pos; for(int i=1;i<=cnt;++i){ if(out[i]==0) {count++; pos=i;} } //printf("count==%d\n",count); //printf("pos") if(count==1){ for(int i=1;i<=n;++i) if(belong[i]==pos) sum++; printf("%d\n",sum); } else printf("0\n"); } return 0; }