POJ 3180 The Cow Prom tarjan
http://poj.org/problem?id=3180
还牛举行正式舞会,无语 题意写的那么纠结干嘛
就是求一个有向图中 所含节点个数 大于等于2的强连通分量的个数
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define Min(a,b)a<b?a:b #define nMAX 10002 #define mMAX 50002 using namespace std; int head[nMAX],dfn[nMAX],low[nMAX],stack[nMAX],node_sta[nMAX];//栈中点的个数 int s_edge,n,top,atype,times; bool insta[nMAX]; struct { int to,next; }edge[mMAX]; void addedge(int u,int v) { s_edge++; edge[s_edge].to=v; edge[s_edge].next=head[u]; head[u]=s_edge; return ; } void tarjan(int u) { dfn[u]=++times; low[u]=times; insta[u]=1; stack[++top]=u; int e; for(e=head[u];e;e=edge[e].next) { int v=edge[e].to; if(!dfn[v]) { tarjan(v); low[u]=Min(low[u],low[v]); } else if(insta[v])//!!! low[u]=Min(low[u],dfn[v]); } int j; if(low[u]==dfn[u]) { atype++; do { j=stack[top--]; insta[u]=0; node_sta[atype]++; }while(j!=u); } return ; } void init() { s_edge=0; top=0; atype=0; times=0; memset(head,0,sizeof(head)); memset(insta,0,sizeof(insta)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(node_sta,0,sizeof(node_sta)); return ; } int main() { int m,u,v,i; while(~scanf("%d%d",&n,&m)) { init(); while(m--) { scanf("%d%d",&u,&v); addedge(u,v); } for(i=1;i<=n;i++) if(!dfn[i]) tarjan(i); int ans=0; for(i=1;i<=atype;i++) if(node_sta[i]>=2) ans++; printf("%d\n",ans); } return 0 ; }