您的位置:首页 > 其它

poj 1236 Network of Schools(强连通分量,缩点)

2018-03-18 10:52 465 查看
题意:机房有n个计算机,然后每个计算机连着k个点,现在要传输消息,问
1.你最多要传送消息给几个电脑,可以使机房的所有电脑都受到消息。
2.添加几条边可以是所有电脑都可以相互连接
思路:在一个强连通分量里的是所有电脑都可以相互收到消息,所以我们需要缩点,把原来的图缩成一个DAG,之后找入度为0的点,之后一个DAG需要添加几个边可以变成一个强连通分量呢,答案是max(入度为0的值,出度为0的值)。
上代码:#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stack>
#include <iostream>
const int maxn = 100+10;
using namespace std;
struct node
{
int to,nex;
}edg[maxn*maxn];
int n,cnt = 0 , scc = 0 , Index = 0;
int head[maxn],low[maxn],dfn[maxn],instack[maxn],belong[maxn] , in[maxn] , out[maxn];
void add(int u,int v)
{
edg[cnt].to = v;
edg[cnt].nex = head[u];
head[u] = cnt++;
}
stack<int>S;
void tarjan(int x)
{
Index++;
low[x] = dfn[x] = Index;
S.push(x);
instack[x] = 1;
for(int i = head[x] ; i!=-1 ; i = edg[i].nex)
{
int v = edg[i].to;
if(!dfn[v])
{
tarjan(v);
low[x] = min(low[v],low[x]);
}
else if(instack[v])
{
low[x] = min(dfn[v],low[x]);
}
}
if(low[x] == dfn[x])
{
++scc;
int v;
while(1)
{
v = S.top();
belong[v] = scc;
S.pop();
instack[v] = 0;
if(v == x) break;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
while(!S.empty())S.pop();
memset(instack,0,sizeof(instack));
memset(belong,0,sizeof(belong));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(head,-1,sizeof(head));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
int te;
cnt = 0 ,scc = 0 , Index = 0;
for(int i = 1 ; i <= n ; i++)
{
while(cin>>te)
{
if(te == 0) break;
add(i,te);
}
}
for(int i = 1 ; i <= n ; i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int i = 1 ; i <= n ; i++)
{
for(int j = head[i] ; j!=-1 ; j = edg[j].nex)
{
int v = edg[j].to;
if(belong[i]!=belong[v])
{
out[belong[i]]++;
in[belong[v]] ++;
}
}
}
int ans1 = 0 ,ans2 = 0;
for(int i = 1 ; i <= scc; i++)
{
if(!in[i])
{
ans1++;
}
if(!out[i]) ans2++;
}
if(scc <= 1)printf("1\n0\n");
else printf("%d\n%d\n",ans1,max(ans1,ans2));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: