首页 > 代码库 > 校园网络 usaco

校园网络 usaco

这道题和上一道【最受欢迎的牛】差不多,都是强连通分量的练习题;

第一问实际上就是问缩点后入度为0的点有多少,第二问就是问添加几条边能使缩点后的图变成强连通图;

第一问好做,第二问需要动下脑子,也不难;

技术分享
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<ctime> 5 #include<cstring> 6 #include<string> 7 #include<algorithm> 8 using namespace std; 9 const int maxn=105;10 int n,x,y,v;11 struct node{12     int y,next;13 }e[maxn*maxn<<1];14 int linkk[maxn],len=0;15 int pre[maxn],low[maxn],scc_cnt=0,dfs_clock=0,z[maxn],top=0,in[maxn],out[maxn],sccno[maxn];16 bool b[maxn][maxn];17 void insert(int x,int y){18     e[++len].y=y;19     e[len].next=linkk[x];20     linkk[x]=len;21 }22 void dfs(int x){23     pre[x]=low[x]=++dfs_clock;24     z[++top]=x;25     for(int i=linkk[x];i;i=e[i].next){26         if(!pre[e[i].y]){27             dfs(e[i].y);28             low[x]=min(low[x],low[e[i].y]);29         }30         else if(!sccno[e[i].y])low[x]=min(low[x],pre[e[i].y]);31     }32     if(low[x]==pre[x]){33         scc_cnt++;34         while(true){35             sccno[z[top]]=scc_cnt;36             if(z[top]==x){top--;break;}37             top--;38         }39     }40 }41 void init(){42     scanf("%d",&n);43     for(int i=1;i<=n;i++){44         while(scanf("%d",&x)&&x)insert(i,x);45     }46 }47 void slove(){48     for(int i=1;i<=n;i++)if(!pre[i])dfs(i);49     for(int j=1;j<=n;j++)50         for(int i=linkk[j];i;i=e[i].next){51             x=sccno[j],y=sccno[e[i].y];52             if(x==y||b[x][y])continue;53             b[x][y]=1;in[y]++,out[x]++;54         }55     x=0,y=0;56     for(int i=1;i<=scc_cnt;i++){57         if(!in[i])x++;58         if(!out[i])y++;59     }60     printf("%d\n%d\n",x,scc_cnt==1?0:max(x,y));61 }62 int main(){63     //freopen("1.in","r",stdin);64     //freopen("1.out","w",stdout);65     init();66     slove();67 }
View Code

 

校园网络 usaco