【CF】244C Checkposts
题目需要求啥很明确了。主要思想是先计算机联通块,然后每个块内找到一个最小值(以及该值的次数)。最小值和结果1,次数乘积为结果2。联通块tarjan可解。
1 /* 427C */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 using namespace std; 20 //#pragma comment(linker,"/STACK:102400000,1024000") 21 22 #define mpii map<int,int> 23 #define vi vector<int> 24 #define pii pair<int,int> 25 #define vpii vector<pair<int,int> > 26 #define rep(i, a, n) for (int i=a;i<n;++i) 27 #define per(i, a, n) for (int i=n-1;i>=a;--i) 28 #define pb push_back 29 #define mp make_pair 30 #define fir first 31 #define sec second 32 #define all(x) (x).begin(),(x).end() 33 #define SZ(x) ((int)(x).size()) 34 #define lson l, mid, rt<<1 35 #define rson mid+1, r, rt<<1|1 36 37 const int maxn = 1e5+5; 38 const int mod = 1e9+7; 39 vi vc[maxn]; 40 int low[maxn], bn[maxn], pre[maxn]; 41 int S[maxn], top; 42 int dfs_clock, block; 43 int n, m; 44 int C[maxn]; 45 int mn[maxn], cnt[maxn]; 46 47 void init() { 48 memset(pre, 0, sizeof(pre)); 49 memset(bn, 0, sizeof(bn)); 50 memset(mn, 0x3f, sizeof(mn)); 51 memset(cnt, 0, sizeof(cnt)); 52 dfs_clock = block = top = 0; 53 } 54 55 void tarjan(int u) { 56 int v; 57 58 S[top++] = u; 59 pre[u] = low[u] = ++dfs_clock; 60 rep(i, 0, SZ(vc[u])) { 61 v = vc[u][i]; 62 if (!pre[v]) { 63 tarjan(v); 64 low[u] = min(low[u], low[v]); 65 } else if (!bn[v]) { 66 low[u] = min(low[u], pre[v]); 67 } 68 } 69 70 if (low[u] == pre[u]) { 71 ++block; 72 do { 73 bn[S[--top]] = block; 74 } while (S[top]!=u); 75 } 76 } 77 78 void solve() { 79 rep(i, 1, n+1) 80 if (!pre[i]) 81 tarjan(i); 82 int b, c; 83 84 rep(i, 1, n+1) { 85 b = bn[i]; 86 c = C[i]; 87 if (c< mn[b]) { 88 mn[b] = c; 89 cnt[b] = 1; 90 } else if (c == mn[b]) { 91 ++cnt[b]; 92 } 93 } 94 95 __int64 ans = 1, cost = 0; 96 rep(i, 1, block+1) { 97 cost += mn[i]; 98 ans = (ans * cnt[i])%mod; 99 } 100 101 printf("%I64d %I64d\n", cost, ans); 102 } 103 104 int main() { 105 ios::sync_with_stdio(false); 106 #ifndef ONLINE_JUDGE 107 freopen("data.in", "r", stdin); 108 freopen("data.out", "w", stdout); 109 #endif 110 111 int u, v; 112 113 scanf("%d", &n); 114 rep(i, 1, n+1) 115 scanf("%d", &C[i]);; 116 scanf("%d", &m); 117 while (m--) { 118 scanf("%d %d", &u, &v); 119 vc[u].pb(v); 120 } 121 122 init(); 123 solve(); 124 125 #ifndef ONLINE_JUDGE 126 printf("time = %d.\n", (int)clock()); 127 #endif 128 129 return 0; 130 }