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

poj 2186【Popular Cows】1236【Network of Schools】2553【The Bottom of a Graph】

2012-09-08 22:14 429 查看
三种方法求极大强连通分支的算法,一题一种方法

poj 2186 求牛被所有其它的牛崇拜的个数,在一个强连通分量里面的牛是互相崇拜的,所以如果这个强连通分支被其它牛崇拜那么这里面的牛都被其它牛崇拜.。。。这一题我用的Tarjan算法

View Code

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;

const int maxN = 5000+10;
vector<int> edge[maxN];
int stack1[maxN],top1;
int stack2[maxN],top2;
int del[maxN];
int Time[maxN];
//bool vis[maxN];
int cnt;
int num;
int n,m;
bool out[maxN];
int ans[maxN];

void Gabow(int x)
{
//vis[x] = true;
stack1[top1 ++] = x;
stack2[top2 ++] = x;
Time[x] = cnt ++;
del[x] = 0;

int len = edge[x].size();
for(int i = 0;i < len;i ++)
{
int u = edge[x][i];
if(!Time[u])
{
Gabow(u);
}
else if(!del[u])
{
while(Time[stack2[top2-1]] > Time[u])
{
top2 --;
}
}
}

if(stack2[top2-1] == x)
{
num ++;
top2 --;
do{
del[stack1[top1-1]] = num;
}while(stack1[--top1] != x);
}
}

int main()
{
while(cin >> n,n)
{
cin >> m;
for(int i = 0;i <= n;i ++)
edge[i].clear();

for(int i = 0;i < m;i ++)
{
int u,v;
cin >> u >> v;
edge[v].push_back(u);
}

memset(Time,0,sizeof(Time));
top1 = 0;
top2 = 0;
cnt = 1;
num = 0;
//memset(vis,false,sizeof(vis));
for(int i = 1;i <= n;i ++)
{
if(!Time[i])
Gabow(i);
}
//memset(vis,false,sizeof(vis));
memset(out,false,sizeof(out));
for(int i = 1;i <= n;i ++)
{
int len = edge[i].size();
for(int j = 0;j < len;j ++)
{
if(del[i] != del[edge[i][j]])
{
out[del[edge[i][j]]] = true;
}
}
}
int t = 0;
for(int i = 1;i <= n;i ++)
{
if(!out[del[i]])
{
ans[t ++] = i;
}
}
for(int i = 0;i < t-1;i ++)
{
cout << ans[i] << " ";
}
if(t >= 1)
cout << ans[t-1];
cout << endl;
}

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