您的位置:首页 > 运维架构

poj 2186 Popular Cows (强连通缩点)

2016-06-07 14:50 429 查看
/***************************************************
题目:  Popular Cows(poj 2186)
链接:  http://poj.org/problem?id=2186 算法:  强连通缩点
思想:  首先在一个连通分量上的点性质都是一样的,
所以就找出所有连通图并缩点,得到有向无
环图,已知要是最受欢迎就必须是出度为0点,
并且还是唯一的一个。
***************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;

const int mx=10005;
vector<int>g[mx];
int n,m;
int vs[mx];
int dfs_cut=0,gcc_cut=0;
int dfn[mx],low[mx];
int scc[mx],out[mx];
int ans[mx];
stack<int>s;

void dfs(int u)
{
dfn[u]=low[u]=++dfs_cut;
vs[u]=1;
s.push(u);
for (int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vs[v])
{
dfs(v);
low[u]=min(low[v],low[u]);
}
else if (!scc[v]) low[u]=min(low[u],dfn[v]);
}
if (low[u]==dfn[u])
{
gcc_cut++;
int cut=0;
while (1)
{
int v=s.top();
cut++;
s.pop();
scc[v]=gcc_cut;
if (u==v) break;

}
ans[gcc_cut]=cut;
}
}

int main()
{
scanf("%d%d",&n,&m);
int u,v;
while (m--)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
}
for (int i=1;i<=n;i++)
{
if (!vs[i]) dfs(i);
}

for (u=1;u<=n;u++)
{
for (int i=0;i<g[u].size();i++)
{
v=g[u][i];
if (scc[u]==scc[v]) continue;
out[scc[u]]=1;
}
}
int flag=0,ans1;
for (int i=1;i<=gcc_cut;i++)
{
if (!out[i])
{
flag++;
ans1=ans[i];
}
}
if (flag==1) printf("%d\n",ans1);
else printf("0\n");

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