您的位置:首页 > 其它

POJ_1236 强连通分支

2010-10-26 19:13 295 查看
http://poj.org/problem?id=1236

#include <iostream>
#include <string.h>
#include <stack>
#define MAX 101
using namespace std;
int n,g[MAX][MAX],tmp,in[MAX],out[MAX];
int dfn[MAX],low[MAX],index=1,cnt=0,belong[MAX];
bool instack[MAX];
stack<int> Q;
int min(int a,int b)
{
return a<b?a:b;
}
int max(int a,int b)
{
return a>b?a:b;
}
void init()
{
memset(g,0,sizeof(g));
memset(instack,false,sizeof(instack));
cin>>n;
for (int i=1;i<=n;i++)//建图
while (1)
{
cin>>tmp;
if (tmp==0)
break;
g[i][tmp]=true;
}
}
void tarjan(int x)//求连通分支
{
dfn[x]=low[x]=index;
index++;
Q.push(x);
instack[x]=true;
for (int i=1;i<=n;i++)
{
if (!g[x][i])
continue;
if (!dfn[i])
{
tarjan(i);
low[x]=min(low[x],low[i]);
}
else if (instack[i])
low[x]=min(low[x],dfn[i]);
}
if (low[x]==dfn[x])
{
cnt++;
while (1)
{
tmp=Q.top();
Q.pop();
belong[tmp]=cnt;
instack[tmp]=false;
if (tmp==x)
break;
}
}
}
void q2()
{
int ans1=0,ans2=0,i,j;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++) //对于强连通分支缩点,并算出入度与出度
{
if (!g[i][j])
continue;
if (belong[i]!=belong[j])
{
in[belong[j]]++;
out[belong[i]]++;
}
}
for (i=1;i<=cnt;i++)
{
if (!in[i])
ans1++;
if (!out[i])
ans2++;
}
if (cnt==1)
cout<<1<<endl<<0<<endl;
else
cout<<ans1<<endl<<max(ans1,ans2)<<endl;
}
void display()
{
init();
for (int i=1;i<=n;i++)
if (!dfn[i])
tarjan(i);
q2();
}
int main()
{
// freopen("in.txt","r",stdin);
display();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: