http://acm.nyist.net/JudgeOnline/problem.php?pid=120&&强连通分量

来源:互联网 发布:什么牌子足球鞋知乎 编辑:程序博客网 时间:2024/06/07 19:40

题意:让一个图变成强连通图,最少需要添加多少边

思路:先求出强连通图的个数,然后缩边后比较图中入度为0和出度为0的顶点个数


 #include<iostream>#include<string>#include<string.h>#include<algorithm>#define N 101#define M 10010using namespace std;bool istack[N];int head[N],dfn[N],low[N],stack[N],belong[N],out[N],in[N];int n,m,res,indexx,num,top;typedef struct str{int to;int next;}Node;Node node[M];void initt(){  memset(head,-1,sizeof(head));   memset(dfn,0,sizeof(dfn));   memset(low,0,sizeof(low));   memset(out,0,sizeof(out));   memset(belong ,0,sizeof(belong));   memset(istack,false,sizeof(istack));   memset(stack,0,sizeof(stack));   memset(in,0,sizeof(in));res=top=num=0;indexx=1;}void dfs(int i){dfn[i]=low[i]=indexx++;istack[i]=true;stack[top++]=i;for(int j=head[i];j!=-1;j=node[j].next){ int v=node[j].to; if(!dfn[v]) { dfs(v); low[i]=min(low[i],low[v]); } else if(istack[v]) low[i]=min(dfn[v],low[i]);}int u;if(dfn[i]==low[i]){res++;do{ u=stack[--top];belong[u]=res;istack[u]=false;}while(i!=u);}}void tarjan(){for(int i=1;i<=n;++i)if(!dfn[i]) dfs(i);}void solve(){for(int i=1;i<=n;++i)  for(int j=head[i];j!=-1;j=node[j].next)if(belong[i]!=belong[node[j].to]){out[belong[i]]++;in[belong[node[j].to]]++;     }if(res==1) cout<<"0"<<endl;//当图本身就是强连通图时else{int p=0,q=0;for(int i=1;i<=res;++i){ if(!out[i]) p++;   if(!in[i]) q++;}cout<<max(p,q)<<endl;}}int main(){  //freopen("c:\\Input.txt","r",stdin);   //freopen("c:\\Out.txt","w",stdout);int T;cin>>T;while(T--){    initt();cin>>n;for(int i=1;i<=n;++i){   int flag=0;int a;     while(cin>>a&&a) {  node[num].to=a;node[num].next=head[i];head[i]=num++; } }tarjan();solve();     }return 0;}                


原创粉丝点击