zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    bzoj-2748 2748: [HAOI2012]音量调节(dp)
    bzoj-2338 2338: [HNOI2011]数矩形(计算几何)
    bzoj-3444 3444: 最后的晚餐(组合数学)
    codeforces 709E E. Centroids(树形dp)
    codeforces 709D D. Recover the String(构造)
    codeforces 709C C. Letters Cyclic Shift(贪心)
    codeforces 709B B. Checkpoints(水题)
    codeforces 709A A. Juicer(水题)
    Repeat Number
    hdu 1003 Max Sum (动态规划)
  • 原文地址:https://www.cnblogs.com/Aragaki/p/9602164.html
Copyright © 2011-2022 走看看