BZOJ1791 基环树直径
非递归版4S
1 /************************************************************** 2 Problem: 1791 3 User: 18357 4 Language: C++ 5 Result: Accepted 6 Time:4556 ms 7 Memory:120132 kb 8 ****************************************************************/ 9 #include <cstdio> 10 #include <cstring> 11 #include <algorithm> 12 #include <stack> 13 #include <cctype> 14 #include <iostream> 15 #define N 1050000 16 using namespace std; 17 inline int getc() 18 { 19 static const int L = 1 << 15; 20 static char buf[L], *S = buf, *T = buf; 21 if (S == T) 22 { 23 T = (S = buf) + fread(buf, 1, L, stdin); 24 if (S == T) 25 { 26 return EOF; 27 } 28 } 29 return *S++; 30 } 31 inline int getint() 32 { 33 int c; 34 while (!isdigit(c = getc())); 35 int tmp = c - '0'; 36 while (isdigit(c = getc())) 37 { 38 tmp = (tmp << 1) + (tmp << 3) + c - '0'; 39 } 40 return tmp; 41 } 42 struct Syndra 43 { 44 int u, v, len, next; 45 } e[N]; 46 struct Fiona 47 { 48 int edge, flag1, flag2; 49 long long temp, max1, max2; 50 } s[N]; 51 int head[N], cnt, n; 52 int visit[N], next[N], len[N]; 53 int i, j, k; 54 long long sa[N], pre[N], ans; 55 void add(int u, int v, int len) 56 { 57 cnt++; 58 e[cnt].u = u; 59 e[cnt].v = v; 60 e[cnt].len = len; 61 e[cnt].next = head[u]; 62 head[u] = cnt; 63 } 64 int que[N << 1]; 65 long long sum[N << 1], ret; 66 long long dp(int num) 67 { 68 int top, tail; 69 int u, b, star; 70 int et; 71 for (et = 1; et < (num << 1); et++) 72 { 73 sum[et] = sum[et - 1] + pre[(et - 1) >= num ? (et - 1 - num) : (et - 1)]; 74 } 75 top = tail = 0; 76 que[tail++] = 0; 77 for (et = 1; et < (num << 1); ++et) 78 { 79 while (top < tail && et - que[top] >= num) 80 { 81 ++top; 82 } 83 u = que[top]; 84 ret = max(ret, sa[et >= num ? et - num : et] + sa[u >= num ? u - num : u] + sum[et] - sum[u]); 85 while (top < tail && sa[et >= num ? et - num : et] >= sa[que[tail - 1] >= num ? que[tail - 1] - num : que[tail - 1]] + sum[et] - sum[que[tail - 1]]) 86 { 87 --tail; 88 } 89 que[tail++] = et; 90 } 91 return ret; 92 } 93 void build() 94 { 95 cnt = 1; 96 memset(head, 0, sizeof(head)); 97 memset(visit, 0, sizeof(visit)); 98 n = getint(); 99 for (i = 1; i <= n; i++) 100 { 101 next[i] = getint(); 102 len[i] = getint(); 103 add(next[i], i, len[i]); 104 } 105 } 106 stack<int>sk; 107 int fa[N]; 108 void dfs(int x) 109 { 110 if (s[x].edge == 0) 111 { 112 sk.pop(); 113 if (s[x].flag2) 114 { 115 ret = max(ret, s[x].max1 + s[x].max2); 116 } 117 if (visit[x] == -1) 118 { 119 return ; 120 } 121 x = sk.top(); 122 { 123 int v, tt = s[x].edge; 124 v = e[tt].v; 125 visit[v] = i; 126 s[x].temp = s[v].max1 + e[tt].len; 127 if (s[x].max1 < s[x].temp) 128 { 129 if (s[x].flag1) 130 { 131 s[x].max2 = s[x].max1, s[x].flag2 = 1; 132 } 133 else 134 { 135 s[x].flag1 = 1; 136 } 137 s[x].max1 = s[x].temp; 138 } 139 else if (s[x].max2 < s[x].temp) 140 { 141 s[x].max2 = s[x].temp, s[x].flag2 = 1; 142 } 143 s[x].edge = e[tt].next; 144 } 145 return ; 146 } 147 int v, tt = s[x].edge; 148 v = e[tt].v; 149 if (visit[v] == -1) 150 { 151 s[x].edge = e[tt].next; 152 return ; 153 } 154 fa[v] = x; 155 s[v].edge = head[v]; 156 sk.push(v); 157 } 158 long long handle(int x) 159 { 160 s[x].edge = head[x]; 161 sk.push(x); 162 while (!sk.empty()) 163 { 164 dfs(sk.top()); 165 } 166 return s[x].max1; 167 } 168 int main() 169 { 170 int u, v; 171 build(); 172 for (i = 1; i <= n; i++) 173 { 174 if (!visit[i]) 175 { 176 for (u = i; !visit[u]; u = next[u]) 177 { 178 visit[u] = i; 179 } 180 if (visit[u] == i) 181 { 182 ret = 0; 183 cnt = 0; 184 visit[u] = -1; 185 for (v = next[u]; v != u; v = next[v]) 186 { 187 visit[v] = -1; 188 } 189 v = u; 190 do 191 { 192 pre[cnt] = len[v]; 193 sa[cnt++] = handle(v); 194 v = next[v]; 195 } 196 while (v != u); 197 ans += dp(cnt); 198 } 199 } 200 } 201 cout << ans; 202 return 0; 203 }
自己写的递归RE待修改版
1 /*Huyyt*/ 2 #include<bits/stdc++.h> 3 #define mem(a,b) memset(a,b,sizeof(a)) 4 #define pb push_back 5 using namespace std; 6 typedef long long ll; 7 typedef unsigned long long ull; 8 using namespace std; 9 const int MAXN = 1e6 + 5, MAXM = 1e6 + 5; 10 int to[MAXM << 1], nxt[MAXM << 1], Head[MAXN], ed = 1; 11 int value[MAXM << 1]; 12 int i, v; 13 inline void addedge(int u, int v, int val) 14 { 15 to[++ed] = v; 16 nxt[ed] = Head[u]; 17 value[ed] = val; 18 Head[u] = ed; 19 } 20 inline void read(int &v) 21 { 22 v = 0; 23 char c = 0; 24 int p = 1; 25 while (c < '0' || c > '9') 26 { 27 if (c == '-') 28 { 29 p = -1; 30 } 31 c = getchar(); 32 } 33 while (c >= '0' && c <= '9') 34 { 35 v = (v << 3) + (v << 1) + c - '0'; 36 c = getchar(); 37 } 38 v *= p; 39 } 40 bool circle[MAXN]; 41 int vis[MAXN], cnt; 42 int nnxt[MAXN], nxtcircle[MAXN]; 43 int que[MAXN << 1]; 44 ll dpd[MAXN], sum[MAXN << 1], pre[MAXN]; 45 ll sa[MAXN], ansnow, anser; 46 stack<int> sk; 47 void dfs(int x, int pre) 48 { 49 vis[x] = 1; 50 for (int v, i = Head[x]; i; i = nxt[i]) 51 { 52 v = to[i]; 53 if (pre != -1 && i == (pre ^ 1)) 54 { 55 continue; 56 } 57 if (vis[v] == 1) 58 { 59 circle[x] = true; 60 nxtcircle[x] = nnxt[x] = i; 61 int cur; 62 cur = to[nxtcircle[x]]; 63 while (cur != x) 64 { 65 circle[cur] = true; 66 nxtcircle[cur] = nnxt[cur]; 67 cur = to[nxtcircle[cur]]; 68 } 69 } 70 else if (vis[v] == 2) 71 { 72 continue; 73 } 74 else 75 { 76 nnxt[x] = i; 77 dfs(v, i); 78 } 79 } 80 vis[x] = 2; 81 } 82 void ZJdp(int x) 83 { 84 vis[x] = 1; 85 for (int v, i = Head[x]; i; i = nxt[i]) 86 { 87 v = to[i]; 88 if (vis[v]) 89 { 90 continue; 91 } 92 ZJdp(v); 93 if (!circle[v]) 94 { 95 ansnow = max(ansnow, dpd[x] + dpd[v] + value[i]); 96 dpd[x] = max(dpd[x], dpd[v] + value[i]); 97 } 98 99 } 100 } 101 int main() 102 { 103 int n; 104 int u; 105 read(n); 106 for (i = 1; i <= n; i++) 107 { 108 read(u), read(v); 109 addedge(i, u, v), addedge(u, i, v); 110 } 111 for (i = 1; i <= n; i++) 112 { 113 if (!vis[i]) 114 { 115 dfs(i, -1); 116 } 117 } 118 mem(vis, 0); 119 int top, tail, et, cur; 120 for (i = 1; i <= n; i++) 121 { 122 if (circle[i]) 123 { 124 if (!vis[i]) 125 { 126 ansnow = 0; 127 ZJdp(i); 128 top = tail = cnt = 0; 129 que[tail++] = 0; 130 cur = to[nxtcircle[i]]; 131 sa[cnt] = dpd[i]; 132 pre[cnt++] = value[nxtcircle[i]]; 133 while (cur != i) 134 { 135 sa[cnt] = dpd[cur]; 136 pre[cnt++] = value[nxtcircle[cur]]; 137 cur = to[nxtcircle[cur]]; 138 } 139 for (et = 1; et < (cnt << 1); et++) 140 { 141 sum[et] = sum[et - 1] + pre[(et - 1) >= cnt ? (et - 1 - cnt) : (et - 1)]; 142 } 143 for (et = 1; et < (cnt << 1); ++et) 144 { 145 while (top < tail && et - que[top] >= cnt) 146 { 147 ++top; 148 } 149 u = que[top]; 150 ansnow = max(ansnow, sa[et >= cnt ? et - cnt : et] + sa[u >= cnt ? u - cnt : u] + sum[et] - sum[u]); 151 while (top < tail && sa[et >= cnt ? et - cnt : et] >= sa[que[tail - 1] >= cnt ? que[tail - 1] - cnt : que[tail - 1]] + sum[et] - sum[que[tail - 1]]) 152 { 153 --tail; 154 } 155 que[tail++] = et; 156 } 157 anser += ansnow; 158 } 159 } 160 } 161 printf("%lld", anser); 162 return 0; 163 }