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 ",ans1,ans2) ; 89 return 0 ; 90 }