poj1236学校网络——连通块
Posted Zinn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1236学校网络——连通块相关的知识,希望对你有一定的参考价值。
题目:http://poj.org/problem?id=1236
通过传输文件的特点可以看出要先求强联通分量,缩点;
问题1:即缩点后入度为0的点,从它们开始传文件可以传给所有学校;
问题2:对于所有入度为0、出度为0的点,对应连一条边;多余的随便再连一下就可以,所以答案是max(入度为0点数,出度为0点数);
需要特判一下没有入度为0的点,也就是整个图是一个强联通分量时,输出1和0。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const MAXN=105; int n,head[MAXN],ct,dfn[MAXN],low[MAXN],rd[MAXN],cd[MAXN],ans,sta[MAXN],tim,top; int cr,col[MAXN],r0,c0; bool vis[MAXN]; struct N{ int hd,to,next; N(int h=0,int t=0,int n=0):hd(h),to(t),next(n) {} }edge[MAXN*MAXN]; void tarjan(int x) { // cout<<x<<endl; tim++; dfn[x]=tim;low[x]=tim; vis[x]=1;sta[++top]=x; for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(!dfn[u]) { tarjan(u); low[x]=min(low[x],low[u]); } else if(vis[u]) low[x]=min(low[x],dfn[u]); } if(dfn[x]==low[x]) { cr++; while(sta[top]!=x) { int t=sta[top]; vis[t]=0;col[t]=cr; top--; } vis[x]=0;col[x]=cr;top--; } } int main() { scanf("%d",&n); int x; for(int i=1;i<=n;i++) while(1) { scanf("%d",&x); if(!x)break; edge[++ct]=N(i,x,head[i]);head[i]=ct; } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=ct;i++) { int u=edge[i].hd; int v=edge[i].to; if(col[u]!=col[v]) { rd[col[v]]++;cd[col[u]]++; } } for(int i=1;i<=cr;i++) { if(!rd[i])r0++; if(!cd[i])c0++; } if(cr==1)printf("1\n0"); else printf("%d\n%d",r0,max(r0,c0)); return 0; }
以上是关于poj1236学校网络——连通块的主要内容,如果未能解决你的问题,请参考以下文章