POJ 2762 Going from u to v or from v to u? tarjan+缩点
http://poj.org/problem?id=2762
就是判断一个图是不是 弱连通
tarjan , 缩点之后,如果缩点图的 入度为一的点有一个 并且 出度为一的点 有一个 则是弱连通
开始把有向边都改成无向边 用dfs遍历 只要图连一块就是弱连通图 ,结果证明是错滴
下图
(图一)这个图就不连通,但是如果依照刚才的dfs把有向边变成无向边就错了
还有一个地方
(图二)
#include<iostream>
#include<cstdio>
#include<cstring>
#define nMAX 10010
#define mMAX 50010
using namespace std;
int head[nMAX],belon[nMAX],out[nMAX],stack[nMAX],s_node[nMAX],
dfn[nMAX],low[nMAX];
int atype,times,n,s_edge,top;
bool instack[nMAX];
struct Edge
{
int u,v,nxt;
}edge[mMAX];
void addedge(int u,int v)
{
s_edge++;
edge[s_edge].u=u;
edge[s_edge].v=v;
edge[s_edge].nxt=head[u];
head[u]=s_edge;
}
int min(int a,int b)
{
return a<b?a:b;
}
void tarjan(int u)
{
dfn[u]=low[u]=++times;
instack[u]=1;
stack[++top]=u;
for(int e=head[u];e;e=edge[e].nxt)
{
int v=edge[e].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
low[u]=min(low[u],dfn[v]);
}
int j;
if(low[u]==dfn[u])
{
atype++;
do{
j=stack[top--];
instack[j]=0;
s_node[atype]++;
belon[j]=atype;
}while(j!=u);
}
}
void init()
{
atype=0;
times=0;
top=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(out,0,sizeof(out));
memset(instack,0,sizeof(instack));
memset(s_node,0,sizeof(s_node));
}
int main()
{
int i,j,m;
while(~scanf("%d%d",&n,&m))
{
init();
memset(head,0,sizeof(head));
s_edge=0;
while(m--)
{
scanf("%d%d",&i,&j);
addedge(i,j);
}
for(i=1;i<=n;i++)
{
if(!dfn[i])tarjan(i);
}
//Ëõµã
for(int e=1;e<=s_edge;e++)
{
int u=edge[e].u,v=edge[e].v;
if(belon[u]!=belon[v])
out[belon[u]]++;
}
int cnt=0,mark;
for(i=1;i<=atype;i++)
{
if(out[i]==0)mark=i,cnt++;
}
if(cnt==1)printf("%d\n",s_node[mark]);
else printf("0\n");
}
return 0;
}

浙公网安备 33010602011771号