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
  • 相关阅读:
    又联考了一场,感觉自己好菜啊,T1没写出来,后来花了一个早上调试。QAQ。最后发现是个-1还有取模没打。。。TAT。。。难受极了!!!
    又联考了一场,感觉自己好菜啊,T2推出了公式但是不会逆元QAQ,难受啊!!!不过都确实是一道逆元的好题撒!
    USACO 2006 November Gold Corn Fields
    SCOI 2005 互不侵犯
    PKU P2411 Mondriaan's Dream
    一道装呀(状压)DP
    继续写高精!noip2012国王游戏。。。
    上两道省选的高精吧!
    找丑数
    本地访问weblogic控制台无反应,关闭linux操作系统防火墙
  • 原文地址:https://www.cnblogs.com/Aragaki/p/9602164.html
Copyright © 2011-2022 走看看