tarjan模板

tarjan模板

 

 1 #include <bits/stdc++.h> 
 2 #define LL long long 
 3 #define For(i,j,k) for(int i=j;i<=k;i++) 
 4 using namespace std ; 
 5 
 6 const int N = 100011,M = 300011,inf = 2e9,mod = 1e9+7  ; 
 7 struct edge{
 8     int to,val,pre ; 
 9 }e[M];
10 int n,p,m,cnt,Ti,top ; 
11 LL ans1,ans2 ; 
12 int visit[N],cost[N],dfn[N],low[N],st[N],head[N],tmp[N]  ; 
13 
14 inline int read() 
15 {
16     int x = 0 , f = 1 ; 
17     char ch = getchar() ; 
18     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 
19     while(ch>='0'&&ch<='9') { x = x * 10+ch-48 ; ch = getchar() ; } 
20     return x * f ;  
21 }
22 
23 inline void add(int x,int y) 
24 {
25     e[++cnt].to = y ; 
26     e[cnt].pre = head[x] ; 
27     head[x] = cnt ; 
28 }
29 
30 inline void tarjan(int u) 
31 {
32     int v ; 
33     dfn[u] = low[u] = ++Ti ; 
34     visit[u] = 1 ;    // 
35     st[++top] = u ; 
36     for(int i=head[u];i;i=e[i].pre) {
37         v = e[i].to ; 
38         if(visit[v]==3) continue ; 
39         if(visit[v]==0) {
40             tarjan( v ) ; 
41             low[ u ]=min(low[u],low[v] ) ; 
42         }
43         else {
44             low[ u ] = min(low[u],dfn[v]) ; 
45         }
46     }
47     
48     
49     if(dfn[ u ]==low[ u ]) {
50         tmp[0] = 0 ; 
51         while(st[top]!=u) {
52             tmp[++tmp[0]] = st[top] ;  
53             top-- ; 
54         }
55         tmp[++tmp[0]] = st[top] ; top-- ; 
56         
57         
58         int mn = inf,sum = 0 ; 
59         For(i,1,tmp[0]) {
60             v = tmp[ i ] ;
61             visit[ v ] = 3 ;  
62             if(cost[ v ] < mn) mn = cost[ v ] ; 
63         }
64         ans1+=mn ; 
65         For(i,1,tmp[0]) {
66             v = tmp[ i ] ; 
67             if(cost[v]==mn) sum++ ; 
68         }
69         ans2 = ans2 * sum % mod ; 
70     }
71 }
72 
73 int main() 
74 {
75     n = read() ; 
76     For(i,1,n) cost[ i ] = read() ; 
77     m = read() ; 
78     int x,y ; 
79     For(i,1,m) {
80         x = read() ; y = read() ; 
81         add(x,y) ; 
82     }
83     ans2 = 1 ; 
84     For(i,1,n) {
85         if(visit[ i ]==0) 
86             tarjan( i ) ;   // 图 一开始可能并不连通 可能会有多个连通块
87     } 
88     printf("%lld %lld\n",ans1,ans2) ; 
89     return 0 ; 
90 }

 

posted @ 2017-09-07 13:42  third2333  阅读(152)  评论(0编辑  收藏  举报