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 }
//BZOJ1791

自己写的递归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 }
View Code

 

posted @ 2018-09-07 01:19  Aragaki  阅读(358)  评论(0编辑  收藏  举报