您的位置:首页 > 编程语言 > Go语言

poj 2762 Going from u to v or from v to u?(强连通、缩点、拓扑)

2013-10-05 13:11 423 查看
题意:(理解错了)在一个洞穴中有多个room,要求任意选两个room:u、v,都能保证u、v之间有通路,注意洞穴中的路是有向边。、

分析:强连通子图中的点必然两两之间可以互通,两个强连通子图之间有通路,必须在树上构成父子关系(不一定相邻),又两两之间有通路,即任意两个点u、v都存在父子关系——所有强连通子图构成一条链。

错误:tarjin初始化忘记更新scc_cnt=dfs_clock=0;

#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;

const int MAXN=1111;

struct Edge{
int v,next;
Edge(){}
Edge(int _v,int _next):v(_v),next(_next){}
}edge[MAXN*10];

struct Tp{
int u,c;
Tp(){}
Tp(int _u,int _c):u(_u),c(_c){}
};

int pre[MAXN],low[MAXN],sccno[MAXN],scc_cnt,dfs_clock;
int head[MAXN],tol;
stack<int>stk;

//int mp[MAXN][MAXN];//去重边反而跑的时间更长
vector<int>G[MAXN];

int in[MAXN],color[MAXN];
queue<Tp>q;

void init()
{
tol=0;
memset(head,-1,sizeof(head));
}

void add(int u,int v)
{
edge[tol]=Edge(v,head[u]);
head[u]=tol++;
}

void dfs(int u)
{
int v;
pre[u]=low[u]=++dfs_clock;
stk.push(u);
for(int i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!pre[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}else if(!sccno[v])
low[u]=min(low[u],pre[v]);
}
if(pre[u]==low[u]){
scc_cnt++;
do{
v=stk.top();
stk.pop();
sccno[v]=scc_cnt;
}while(u!=v);
}
}

void find_scc(int n)
{
dfs_clock=scc_cnt=0;
memset(pre,0,sizeof(pre));
memset(low,0,sizeof(low));
memset(sccno,0,sizeof(sccno));

for(int i=1;i<=n;i++)
if(!pre[i])
dfs(i);
}

int main()
{
int T;
int n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);

init();
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}

find_scc(n);

memset(in,0,sizeof(in));
for(int i=1;i<=scc_cnt;i++)
G[i].clear();
//memset(mp,0,sizeof(mp));
for(int i=1;i<=n;i++)
for(int j=head[i];j!=-1;j=edge[j].next)
if(sccno[i]!=sccno[edge[j].v]){
//if(mp[sccno[i]][sccno[edge[j].v]]==0){
G[sccno[i]].push_back(sccno[edge[j].v]);
//mp[sccno[i]][sccno[edge[j].v]]=1;
in[sccno[edge[j].v]]++;
//}
}
for(int i=1;i<=scc_cnt;i++)
if(!in[i])
q.push(Tp(i,1));

memset(color,0,sizeof(color));
Tp e;
while(!q.empty())
{
e=q.front();q.pop();
color[e.c]++;
int sz=G[e.u].size();
for(int i=0;i<sz;i++)
{
in[G[e.u][i]]--;
if(in[G[e.u][i]]==0){
q.push(Tp(G[e.u][i],e.c+1));
}
}
}

int flog=1;
for(int i=1;i<=e.c;i++)
if(color[i]>1){
flog=0;
break;
}

if(!flog)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}


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