bzoj1040: [ZJOI2008]骑士

破环qwq

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<iostream>
  6 
  7 using namespace std;
  8 
  9 void setIO(const string& s) {
 10     freopen((s + ".in").c_str(), "r", stdin);
 11     freopen((s + ".out").c_str(), "w", stdout);
 12 }
 13 template<typename Q> Q read(Q& x) {
 14     static char c, f;
 15     for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
 16     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
 17     if(f) x = -x;
 18     return x;
 19 }
 20 template<typename Q> Q read() {
 21     static Q x; read(x); return x;
 22 }
 23 typedef long long LL;
 24 const int N = 2000000 + 10;
 25 
 26 struct Edge {
 27     int to;
 28     Edge *next;
 29     Edge() {}
 30     Edge(int to, Edge *next) : to(to), next(next) {}
 31 }pool[N * 2], *fir[N], *pis = pool;
 32 
 33 void AddEdge(int u, int v) {
 34     fir[u] = new(pis++) Edge(v, fir[u]);
 35     fir[v] = new(pis++) Edge(u, fir[v]);
 36 }
 37 
 38 int r1, r2;
 39 
 40 int val[N], vis[N], fa[N];
 41 
 42 void find_circle(int u) {
 43     vis[u] = 1;
 44     for(Edge *p = fir[u]; p; p = p->next) {
 45         int v = p->to;
 46         if(vis[v]) {
 47             if(fa[v] != u && fa[u] != v) r1 = u, r2 = v;
 48         }else fa[v] = u, find_circle(v);
 49     }
 50 }
 51 
 52 LL d[N][2];
 53 
 54 int flag[N];
 55 int vis_sign;
 56 
 57 void dfs(int u) {
 58     flag[u] = vis_sign;
 59     d[u][0] = 0;
 60     d[u][1] = val[u];
 61     for(Edge *p = fir[u]; p; p = p->next) {
 62         int v = p->to;
 63         if((u == r1 && v == r2) || (u == r2 && v == r1)) continue;
 64         if(flag[v] != vis_sign) {
 65             dfs(v);
 66             d[u][0] += max(d[v][0], d[v][1]);
 67             d[u][1] += d[v][0];
 68         }
 69     }
 70 }
 71 
 72 int main() {
 73 #ifdef DEBUG
 74     freopen("in.txt", "r", stdin);
 75     freopen("out.txt", "w", stdout);
 76 #endif
 77     
 78     int n = read<int>();
 79     for(int u = 1; u <= n; u++) {
 80         read(val[u]);
 81         AddEdge(u, read<int>());
 82     }
 83     
 84     LL res = 0;
 85     
 86     for(int u = 1; u <= n; u++) if(!vis[u]) {
 87         r1 = r2 = 0;
 88         find_circle(u);
 89         LL tmp = 0;
 90         vis_sign = 1;    
 91         if(r1) {
 92             dfs(r1), tmp = d[r1][0];
 93             vis_sign = 2, dfs(r2), tmp = max(tmp, d[r2][0]);
 94         }else dfs(u), tmp = max(d[u][0], d[u][1]);
 95         res += tmp;
 96     }
 97     
 98     printf("%lld
", res);
 99     
100     return 0;
101 }
View Code
原文地址:https://www.cnblogs.com/showson/p/5104827.html