首页 > 代码库 > POJ 1236 Network of Schools(强连通分量)
POJ 1236 Network of Schools(强连通分量)
题目地址:POJ 1236
这个题的大意是求最少往多少点发送消息可以使任意一个点都能收到消息和最少增加多少条边可以使图为连通图。对于第一个问题,可以求入度为0的强连通块的块数,因为只有入度为0的强连通块是无法从外界接受信息的,而只要有一个入度的话,那整个连通块就都可以接收到信息。第二个问题则是求入度为0的强连通块与出度为0的强连通块的个数的最大值。
代码如下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; int head[200], cnt, index, top, ans, cntin, cntout, in[200], out[200]; int dfn[200], belong[200], instack[200], stak[200], low[200]; struct node { int u, v, next; } edge[100000]; void add(int u, int v) { edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } void init() { memset(head,-1,sizeof(head)); cnt=0; memset(instack,0,sizeof(instack)); memset(dfn,0,sizeof(dfn)); top=index=ans=0; cntin=cntout=0; memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); } void tarjan(int u) { dfn[u]=low[u]=++index; instack[u]=1; stak[++top]=u; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(!dfn[v]) { tarjan(v); low[u]=min(low[v],low[u]); } else if(instack[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]) { ans++; while(1) { int v=stak[top--]; belong[v]=ans; instack[v]=0; if(u==v) break; } } } int main() { int n, i, j, a; scanf("%d",&n); init(); for(i=1; i<=n; i++) { while(scanf("%d",&a)&&a) { add(i,a); } } for(i=1; i<=n; i++) { if(!dfn[i]) tarjan(i); } if(ans==1) printf("1\n0\n"); else { for(i=1; i<=n; i++) { for(j=head[i]; j!=-1; j=edge[j].next) { int v=edge[j].v; if(belong[i]!=belong[v]) { in[belong[v]]++; out[belong[i]]++; } } } for(i=1; i<=ans; i++) { if(!in[i]) cntin++; if(!out[i]) cntout++; } printf("%d\n%d\n",cntin,max(cntin,cntout)); } return 0; }
POJ 1236 Network of Schools(强连通分量)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。