非递归版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. Tomcat服务org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemoryError: Java heap space

    一个运行了很久的项目,最近忽然报错:OOM( java.lang.OutOfMemoryError: Java heap space),异常如下 org.springframework.web.uti ...

  2. yum安装epel源

    国内yum源的安装(163,阿里云,epel)   国内yum源的安装(163,阿里云,epel) ----阿里云镜像源 1.备份 mv /etc/yum.repos.d/CentOS-Base.re ...

  3. js多元运算

    for(var i=1;i<=100;i++){ var f = i%3 == 0, b = i%5 == 0; if(f){ if(b){ console.log("FizzBuzz ...

  4. 利用Fiddler-ImageView识别图像信息及优化图像

    一般情况下,我们用Fiddler来拦截修改数据包,分析数据包,但很少拿它来分析图片. Fiddler里的ImageView视图不仅仅能显示图片,还能解析图片里包含的信息,比如帧数,图片修改时间,版权信 ...

  5. FastAdmin-T

    FastAdmin 注意食用姿势,建议先通读官方文档一次,在看 根据环境及配置的不同,仅作参考 修改mysql表注释ALTER TABLE student COMMENT '学生表'; fastadm ...

  6. TensorFlow实战第一课(session、Variable、Placeholder、Activation Function)

    莫烦tensorflow教学 1.session会话控制 Tensorflow 中的Session, Session是 Tensorflow 为了控制,和输出文件的执行的语句. 运行session.r ...

  7. LeetCode | DP专题详解

    221 medium     221. Maximal Square Medium Given a 2D binary matrix filled with 0's and 1's, find the ...

  8. aliyun挂载oss

    配置 oss 挂载 阿里云 ecs 按照ossfs工具:yum install http://gosspublic.alicdn.com/ossfs/ossfs_1.80.5_centos6.5_x8 ...

  9. linux shadow文件格式弱口令解密

    shadow格式弱口令为linux弱口令,通过kali linux 终端 john --w=字典 加上shadow文件, 扫描完成之后通过john --show 加上shadow文件出结果

  10. RS232与RS485的功能与区别!

    转载于:http://blog.csdn.net/kevinhg/article/details/7367144 RS232接口是1970年由美国电子工业协会(EIA)联合贝尔系统.调制解调器厂家及计 ...