非递归版4S

 /**************************************************************
Problem: 1791
User: 18357
Language: C++
Result: Accepted
Time:4556 ms
Memory:120132 kb
****************************************************************/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <cctype>
#include <iostream>
#define N 1050000
using namespace std;
inline int getc()
{
static const int L = << ;
static char buf[L], *S = buf, *T = buf;
if (S == T)
{
T = (S = buf) + fread(buf, , L, stdin);
if (S == T)
{
return EOF;
}
}
return *S++;
}
inline int getint()
{
int c;
while (!isdigit(c = getc()));
int tmp = c - '';
while (isdigit(c = getc()))
{
tmp = (tmp << ) + (tmp << ) + c - '';
}
return tmp;
}
struct Syndra
{
int u, v, len, next;
} e[N];
struct Fiona
{
int edge, flag1, flag2;
long long temp, max1, max2;
} s[N];
int head[N], cnt, n;
int visit[N], next[N], len[N];
int i, j, k;
long long sa[N], pre[N], ans;
void add(int u, int v, int len)
{
cnt++;
e[cnt].u = u;
e[cnt].v = v;
e[cnt].len = len;
e[cnt].next = head[u];
head[u] = cnt;
}
int que[N << ];
long long sum[N << ], ret;
long long dp(int num)
{
int top, tail;
int u, b, star;
int et;
for (et = ; et < (num << ); et++)
{
sum[et] = sum[et - ] + pre[(et - ) >= num ? (et - - num) : (et - )];
}
top = tail = ;
que[tail++] = ;
for (et = ; et < (num << ); ++et)
{
while (top < tail && et - que[top] >= num)
{
++top;
}
u = que[top];
ret = max(ret, sa[et >= num ? et - num : et] + sa[u >= num ? u - num : u] + sum[et] - sum[u]);
while (top < tail && sa[et >= num ? et - num : et] >= sa[que[tail - ] >= num ? que[tail - ] - num : que[tail - ]] + sum[et] - sum[que[tail - ]])
{
--tail;
}
que[tail++] = et;
}
return ret;
}
void build()
{
cnt = ;
memset(head, , sizeof(head));
memset(visit, , sizeof(visit));
n = getint();
for (i = ; i <= n; i++)
{
next[i] = getint();
len[i] = getint();
add(next[i], i, len[i]);
}
}
stack<int>sk;
int fa[N];
void dfs(int x)
{
if (s[x].edge == )
{
sk.pop();
if (s[x].flag2)
{
ret = max(ret, s[x].max1 + s[x].max2);
}
if (visit[x] == -)
{
return ;
}
x = sk.top();
{
int v, tt = s[x].edge;
v = e[tt].v;
visit[v] = i;
s[x].temp = s[v].max1 + e[tt].len;
if (s[x].max1 < s[x].temp)
{
if (s[x].flag1)
{
s[x].max2 = s[x].max1, s[x].flag2 = ;
}
else
{
s[x].flag1 = ;
}
s[x].max1 = s[x].temp;
}
else if (s[x].max2 < s[x].temp)
{
s[x].max2 = s[x].temp, s[x].flag2 = ;
}
s[x].edge = e[tt].next;
}
return ;
}
int v, tt = s[x].edge;
v = e[tt].v;
if (visit[v] == -)
{
s[x].edge = e[tt].next;
return ;
}
fa[v] = x;
s[v].edge = head[v];
sk.push(v);
}
long long handle(int x)
{
s[x].edge = head[x];
sk.push(x);
while (!sk.empty())
{
dfs(sk.top());
}
return s[x].max1;
}
int main()
{
int u, v;
build();
for (i = ; i <= n; i++)
{
if (!visit[i])
{
for (u = i; !visit[u]; u = next[u])
{
visit[u] = i;
}
if (visit[u] == i)
{
ret = ;
cnt = ;
visit[u] = -;
for (v = next[u]; v != u; v = next[v])
{
visit[v] = -;
}
v = u;
do
{
pre[cnt] = len[v];
sa[cnt++] = handle(v);
v = next[v];
}
while (v != u);
ans += dp(cnt);
}
}
}
cout << ans;
return ;
}

//BZOJ1791

自己写的递归RE待修改版

 /*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MAXN = 1e6 + , MAXM = 1e6 + ;
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], ed = ;
int value[MAXM << ];
int i, v;
inline void addedge(int u, int v, int val)
{
to[++ed] = v;
nxt[ed] = Head[u];
value[ed] = val;
Head[u] = ed;
}
inline void read(int &v)
{
v = ;
char c = ;
int p = ;
while (c < '' || c > '')
{
if (c == '-')
{
p = -;
}
c = getchar();
}
while (c >= '' && c <= '')
{
v = (v << ) + (v << ) + c - '';
c = getchar();
}
v *= p;
}
bool circle[MAXN];
int vis[MAXN], cnt;
int nnxt[MAXN], nxtcircle[MAXN];
int que[MAXN << ];
ll dpd[MAXN], sum[MAXN << ], pre[MAXN];
ll sa[MAXN], ansnow, anser;
stack<int> sk;
void dfs(int x, int pre)
{
vis[x] = ;
for (int v, i = Head[x]; i; i = nxt[i])
{
v = to[i];
if (pre != - && i == (pre ^ ))
{
continue;
}
if (vis[v] == )
{
circle[x] = true;
nxtcircle[x] = nnxt[x] = i;
int cur;
cur = to[nxtcircle[x]];
while (cur != x)
{
circle[cur] = true;
nxtcircle[cur] = nnxt[cur];
cur = to[nxtcircle[cur]];
}
}
else if (vis[v] == )
{
continue;
}
else
{
nnxt[x] = i;
dfs(v, i);
}
}
vis[x] = ;
}
void ZJdp(int x)
{
vis[x] = ;
for (int v, i = Head[x]; i; i = nxt[i])
{
v = to[i];
if (vis[v])
{
continue;
}
ZJdp(v);
if (!circle[v])
{
ansnow = max(ansnow, dpd[x] + dpd[v] + value[i]);
dpd[x] = max(dpd[x], dpd[v] + value[i]);
} }
}
int main()
{
int n;
int u;
read(n);
for (i = ; i <= n; i++)
{
read(u), read(v);
addedge(i, u, v), addedge(u, i, v);
}
for (i = ; i <= n; i++)
{
if (!vis[i])
{
dfs(i, -);
}
}
mem(vis, );
int top, tail, et, cur;
for (i = ; i <= n; i++)
{
if (circle[i])
{
if (!vis[i])
{
ansnow = ;
ZJdp(i);
top = tail = cnt = ;
que[tail++] = ;
cur = to[nxtcircle[i]];
sa[cnt] = dpd[i];
pre[cnt++] = value[nxtcircle[i]];
while (cur != i)
{
sa[cnt] = dpd[cur];
pre[cnt++] = value[nxtcircle[cur]];
cur = to[nxtcircle[cur]];
}
for (et = ; et < (cnt << ); et++)
{
sum[et] = sum[et - ] + pre[(et - ) >= cnt ? (et - - cnt) : (et - )];
}
for (et = ; et < (cnt << ); ++et)
{
while (top < tail && et - que[top] >= cnt)
{
++top;
}
u = que[top];
ansnow = max(ansnow, sa[et >= cnt ? et - cnt : et] + sa[u >= cnt ? u - cnt : u] + sum[et] - sum[u]);
while (top < tail && sa[et >= cnt ? et - cnt : et] >= sa[que[tail - ] >= cnt ? que[tail - ] - cnt : que[tail - ]] + sum[et] - sum[que[tail - ]])
{
--tail;
}
que[tail++] = et;
}
anser += ansnow;
}
}
}
printf("%lld", anser);
return ;
}

BZOJ1791 基环树直径的更多相关文章

  1. luogu 4381 [IOI2008]Island 单调队列 + 基环树直径 + tarjan

    Description 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样 ...

  2. 『Island 基环树直径』

    Island(IOI 2008) Description 你准备浏览一个公园,该公园由 N 个岛屿组成,当地管理部门从每个岛屿 i 出发向另外一个岛屿建了一座长度为 L_i 的桥,不过桥是可以双向行走 ...

  3. [IOI2008/BZOJ1791 岛屿](处理基环树的小技巧&基于bfs树形DP)

    IOI2008/BZOJ1791 岛屿 题目大意是在一个基环树森林里求每一棵基环树的直径①的和. 其实就是树的直径的基环树升级版.我们先把环找出来,然后从环上的每一个节点x出发,并且不经过环上其他节点 ...

  4. 【BZOJ1791】【IOI2008】【基环树】island(status第一速度)

      1791: [Ioi2008]Island 岛屿  Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 908  Solved: 159 [Su ...

  5. bzoj1791[IOI2008]Island岛屿(基环树+DP)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1791 题目大意:给你一棵n条边的基环树森林,要你求出所有基环树/树的直径之和.n< ...

  6. D4 树的直径、重心以及基环树

    第一题第二题鉴上我前几篇博客poj1985 poj1849:https://www.cnblogs.com/Tyouchie/p/10384379.html 第三题:数的重心:poj1655 来自sj ...

  7. BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

  8. BZOJ1791 [Ioi2008]Island 岛屿[基环树+单调队列优化DP]

    基环树直径裸题. 首先基环树直径只可能有两种形式:每棵基环树中的环上挂着的树的直径,或者是挂在环上的两个树的最大深度根之间的距离之和. 所以,先对每个连通块跑一遍,把环上的点找出来,然后对环上每个点跑 ...

  9. bzoj 1791: [Ioi2008]Island 岛屿【基环树+单调队列优化dp】

    我太菜了居然调了一上午-- 这个题就是要求基环树森林的基环树直径和 大概步骤就是找环->dp找每个环点最远能到达距离作为点权->复制一倍环,单调队列dp 找环是可以拓扑的,但是利用性质有更 ...

随机推荐

  1. centOS7忘记密码,修改root账号密码

    centOS7忘记密码,修改root账号密码 RHEL7 的世界发生了变化,重置 root 密码的方式也一样.虽然中断引导过程的旧方法(init=/bin/bash)仍然有效,但它不再是推荐的.“Sy ...

  2. python matplotlib 多图像排列显示

    用OpenCV和matplotlib实现多图排列,代码如下: import cv2 import matplotlib.pyplot as plt img = cv2.imread('C:\\User ...

  3. 系统 --- Linux系统环境搭建

    Linux命令介绍 软硬链接 作用:建立连接文件,linux下的连接文件类似于windows下的快捷方式 分类: 软链接:软链接不占用磁盘空间,源文件删除则软链接失效 硬链接:硬链接只能链接不同文件, ...

  4. JAVA SQL注入漏洞挖掘

    java中sql注入主要发生在model层,黑盒测试sql注入的方法结合两点:1,异常注入后,界面有无明显的aql异常报出.2,查看数据库日志是否有脏数据注入. preparestatement方法是 ...

  5. 隐蔽的bean没有定义错误:No bean named 'SysJdTypeServiceImpl' is defined

    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'SysJdTypeServiceImpl ...

  6. 第四周课程总结&实验报告二

    第四周课程总结 第四周课程总结 本周重点为学习String;首先String用以创建字符串,且通过有一次课堂练习加强理解到:String 类是不可改变的,一旦创建了 String 对象,那它的值就无法 ...

  7. 编程竞赛--关于"数"的概念

    质数:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数. 合数:合数是指自然数中除了能被1和本身整除外,还能被其他数(0除外)整数的数.与之相对的是质数,而1既不属于质数也不属于合 ...

  8. flower 时区设置

    celery 搭配flower使用,flower默认使用的是UTC时间,那么如何在flower中使用当前城市的时间呢 我的环境 celery 3.1.25 ,python 3.69 1.在 app设置 ...

  9. HDU3336 Count the string(kmp

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...

  10. python3.7环境下创建app,运行Django1.11版本项目报错SyntaxError: Generator expression must be parenthesized

    咳咳!!! 今天用命令行创建django项目中的app应用,出现了这样一个错误 这个错误在python3.6版本下安装运行django 1.11版本正常运行,但python3.7版本下运行django ...