以前做过poj的一个判断图是否为弱连通的题,然后,这个题和poj那个差不多。
先强连通缩点,然后重新构图,然后找出包含点数最多的 链 ,统计个数即可,可以用拓扑排序搞~
pS:重新构图时有重边,然后导致统计方案数的重复。。wa了好久。。还是wzc神犇告诉我这个蒟蒻的。。
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 7 #define N 200000 8 #define M 5000000 9 #define BUG system("pause") 10 11 using namespace std; 12 13 int head[N],to[M],next[M]; 14 int dfn[N],low[N]; 15 int st[M],ed[M]; 16 int n,m,cnt,ans,ansnum,mod; 17 int divg,belong[N],t,p,stk[N],val[N]; 18 bool fg[N]; 19 int num[N], in [N],dp[N],q[M],vis[N]; 20 21 inline void add( int u, int v) 22 { 23 to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++ ; 24 } 25 26 inline void read() 27 { 28 memset(head,- 1 , sizeof head); cnt= 0 ; 29 scanf( " %d%d%d " ,&n,&m,& mod); 30 for ( int i= 1 ;i<=m;i++ ) 31 { 32 scanf( " %d%d " ,&st[i],& ed[i]); 33 add(st[i],ed[i]); 34 } 35 } 36 37 inline void dfs( int u) 38 { 39 low[u]=dfn[u]=++ t; 40 stk[++p]=u; fg[u]= true ; 41 for ( int i=head[u];~i;i= next[i]) 42 { 43 if (! dfn[to[i]]) 44 { 45 dfs(to[i]); 46 low[u]= min(low[u],low[to[i]]); 47 } 48 else if (fg[to[i]]) low[u]= min(low[u],dfn[to[i]]); 49 } 50 if (dfn[u]== low[u]) 51 { 52 divg++ ; 53 int tmp=- 1 ; 54 while (tmp!= u) 55 { 56 tmp=stk[p-- ]; 57 belong[tmp]= divg; 58 val[divg]++ ; 59 fg[tmp]= false ; 60 } 61 } 62 } 63 64 inline void topsort() 65 { 66 int h= 1 ,t= 1 ,u; 67 for ( int i= 1 ;i<=divg;i++ ) 68 if ( in [i]== 0 ) 69 { 70 q[t++]= i; 71 dp[i]= val[i]; 72 num[i]= 1 ; 73 } 74 while (h< t) 75 { 76 u=q[h++ ]; 77 for ( int i=head[u];~i;i= next[i]) 78 { 79 in [to[i]]-- ; 80 if ( in [to[i]]== 0 ) q[t++]= to[i]; 81 if (vis[to[i]]==u) continue ; // 有重边!! 82 if (dp[to[i]]<dp[u]+ val[to[i]]) 83 { 84 dp[to[i]]=dp[u]+ val[to[i]]; 85 num[to[i]]= num[u]; 86 } 87 else if (dp[to[i]]==dp[u]+ val[to[i]]) 88 { 89 num[to[i]]=(num[to[i]]+num[u])% mod; 90 } 91 vis[to[i]]= u; 92 } 93 } 94 } 95 96 inline void go() 97 { 98 for ( int i= 1 ;i<=n;i++ ) 99 if (! dfn[i]) dfs(i); 100 memset(head,- 1 , sizeof head); cnt= 0 ; 101 for ( int i= 1 ;i<=m;i++ ) 102 if (belong[st[i]]!= belong[ed[i]]) 103 { 104 add(belong[st[i]],belong[ed[i]]); 105 in [belong[ed[i]]]++ ; 106 } 107 topsort(); 108 for ( int i= 1 ;i<=divg;i++ ) 109 { 110 if (dp[i]> ans) 111 { 112 ans= dp[i]; 113 ansnum= num[i]; 114 } 115 else if (dp[i]==ans) ansnum=(ansnum+num[i])% mod; 116 } 117 printf( " %d\n%d\n " ,ans,ansnum); 118 } 119 120 int main() 121 { 122 read(); 123 go(); 124 return 0 ; 125 }