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; }