您的位置:首页 > 其它

codevs1506传话(kosaraju算法)

2016-04-18 21:46 253 查看
- -   - -   - -   - -

一个()打成[]  看了一晚上.....

/*
求强连通分量 kosaraju算法
边表存图 正反构造两个图
跑两边 分别记下入栈顺序 和每个强连通分量的具体信息
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
#define maxn 1010
#define maxx 10010
using namespace std;
int n,m,num,head1[maxn],head2[maxn],f[maxn],cnt;
int flag[maxn],ans[maxn][maxn];
stack<int>s;
struct node
{
int u,v,per;
}e1[maxx],e2[maxx];
void Input()//输入 构图 e1为正 e2为反
{
int i,x,y;
cin>>n>>m;
for(i=1;i<=m;i++)
{
cin>>x>>y;
num++;
e1[num].u=x;
e1[num].v=y;
e1[num].per=head1[x];
head1[x]=num;
e2[num].u=y;
e2[num].v=x;
e2[num].per=head2[y];
head2[y]=num;
}
}
void Dfs1(int k)
{
f[k]=1;
for(int p=head1[k];p;p=e1[p].per)
{
if(!f[e1[p].v])
Dfs1(e1[p].v);
}
s.push(k);//记录入栈顺序
}
void Dfs2(int k)
{
f[k]=1;
ans[cnt][++ans[cnt][0]]=k;//记下第cnt个强连通分量的每个点
for(int i=head2[k];i;i=e2[i].per)
if(f[e2[i].v]==0)
Dfs2(e2[i].v);
if(ans[cnt][0]>1)flag[k]=1;//如果第 cnt个强连通分量的大小>1 则x属于某个强连通分量
}
void Kosaraju()
{
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)//跑第一遍Dfs 每个点依次入栈
{
if(f[i]==0)
Dfs1(i);
}
memset(f,0,sizeof(f));
while(!s.empty())//跑第二遍Dfs 标记每个点是否属于一个强连通分量 并计算数量
{
int tmp=s.top();
s.pop();
if(f[tmp]==0)
{
cnt++;//计数强连通分量
Dfs2(tmp);
}
}
}
void Printf()
{
for(int i=1;i<=n;i++)
if(flag[i]==1)cout<<"T"<<endl;
else cout<<"F"<<endl;
}
int main()
{
Input();
Kosaraju();
Printf();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: