您的位置:首页 > 其它

POJ 1236 Network of Schools[连通分量]

2013-07-30 22:48 369 查看
题目链接:http://poj.org/problem?id=1236
题目大意:给出N台电脑,电脑间单向连通传送文件
问题1.网络中最少放几个文件保证所有电脑都能接受到文件
问题2.最少向网络中加几条线保证任意放1个文件所有电脑都能接受到
解题思路:
1.求出强连通分量
2.缩点 ,进行重新构图
3.如果入度为0,说明没有文件传输到该网络。解决问题1,统计入度为0的个数即可
4.一个强连通图的入度和出度都不为0。入度为0相当于根root,出度为0相当于叶子leave.max(root, leave)即为答案。
就是需要加的线数,保证整个网络强连通。
若连通分量个数为0,那么答案为0

代码如下:

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 105
#define M 10005
struct Edge
{
int v, next;
}edge[M];

int node
, stack
, instack
, dfn
, out
, in
;
int low
, belong
, index, cnt_edge, n, m, cnt_tar, top;
int ee[M][2];

void add_Edge(int u, int v)
{
edge[cnt_edge].next=node[u];
edge[cnt_edge].v=v;
node[u]=cnt_edge++;
}
void tarjan(int u)
{
int i, j, v;
dfn[u]=low[u]=++index;
stack[++top]=u;
instack[u]=1;
for(i=node[u]; i!=-1; i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u], low[v]);
}
else if(instack[v])
low[u]=min(low[u], dfn[v]);
}
if(dfn[u]==low[u])
{
cnt_tar++;
do
{
j=stack[top--];
instack[j]=0;
belong[j]=cnt_tar;
}while(j!=u);
}

}
void solve()
{
int i;
top=0, index=0, cnt_tar=0;
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
for(i=1; i<=n; i++)
if(!dfn[i])
tarjan(i);
}
int main()
{
int i, u, v;
while(scanf("%d", &n)!=EOF)
{
cnt_edge=0, m=1;
memset(node, -1, sizeof(node));
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
for(i=1; i<=n; i++)
{
while(scanf("%d", &v))
{
if(v==0) break;
ee[m][0]=i, ee[m++][1]=v;
add_Edge(i, v);
}
}
solve();
for(i=1; i<=m; i++)
{
int xx=belong[ee[i][0]], yy=belong[ee[i][1]];
if(xx!=yy)
{
in[yy]++;
out[xx]++;
}
}
int innum=0, outnum=0;
for(i=1; i<=cnt_tar; i++)
{
if(in[i]==0)
innum++;
if(out[i]==0)
outnum++;
}
if(cnt_tar==1)
printf("1\n0\n");
else
printf("%d\n%d\n", innum, max(innum, outnum));
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: