【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
", 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.
", (int)clock());
127     #endif
128     
129     return 0;
130 }
原文地址:https://www.cnblogs.com/bombe1013/p/4595629.html