标签:
2 4 3 3 2 2 0 2 1 3 3 1 0 2 1 0 2
Case 1: 2 0 1 Case 2: 2 0 1 2
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<limits.h> typedef long long LL; using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int maxn=5000+100; const int maxm=100000+10; struct node{ int u,v; int next; }e[maxm],e1[maxn]; int head[maxn],cntE,cntF; int DFN[maxn],low[maxn],h[maxn]; int s[maxm],top,index,cnt; int belong[maxn],instack[maxn]; int dp[maxn],in[maxn],vis[maxn]; int num[maxn]; int n,m; void init() { top=cntE=cntF=0; index=cnt=0; CLEAR(DFN,0); CLEAR(head,-1); CLEAR(instack,0); } void addedge(int u,int v) { e[cntE].u=u;e[cntE].v=v; e[cntE].next=head[u]; head[u]=cntE++; } void Tarjan(int u) { DFN[u]=low[u]=++index; instack[u]=1; s[top++]=u; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].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 v; if(DFN[u]==low[u]) { cnt++; do{ v=s[--top]; belong[v]=cnt; instack[v]=0; }while(u!=v); } } int dfs(int x) { int ans=num[x]; for(int i=h[x];i!=-1;i=e1[i].next) { int v=e1[i].v; if(!vis[v]) { vis[v]=1; ans+=dfs(v); } } return ans; } void work() { REP(i,n) if(!DFN[i]) Tarjan(i); if(cnt==1) { printf("%d\n",n-1); REP(i,n) printf(i==n-1?"%d\n":"%d ",i); return ; } CLEAR(num,0); CLEAR(dp,0); CLEAR(in,0); CLEAR(h,-1); REP(i,n)//马丹,这里卡了我两天 num[belong[i]]++; REP(k,n) { for(int i=head[k];i!=-1;i=e[i].next) { int v=e[i].v; if(belong[k]!=belong[v])//反向建边dfs. { // cout<<"666 "<<endl; e1[cntF].u=belong[v]; e1[cntF].v=belong[k]; e1[cntF].next=h[belong[v]]; h[belong[v]]=cntF++; in[belong[k]]++; } } } REPF(i,1,cnt) { if(!in[i]) { CLEAR(vis,0); dp[i]=dfs(i)-1; } } int ans=0; REPF(i,1,cnt) ans=max(ans,dp[i]); printf("%d\n",ans); int flag=0; REP(i,n) { if(dp[belong[i]]==ans) { if(!flag) printf("%d",i),flag=1; else printf(" %d",i); } } printf("\n"); } int main() { int t,u,v; int cas=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); init(); for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); addedge(u,v); } printf("Case %d: ",cas++); work(); } return 0; }
HDU 3639 Hawk-and-Chicken(Tarjan缩点+反向DFS)
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/4265947.html