首先对于一棵树我们可以tree_dp来解决这个问题,那么对于环上每个点为根的树我们可以求出这个树的一端为根的最长链,并且在tree_dp的过程中更新答案。那么我们对于环,从某个点断开,破环为链,然后再用DP来解决这个问题。

  备注:很久之前的一道题,刚转的c++,然后T了,也懒得改了。

/**************************************************************
Problem: 1791
User: BLADEVIL
Language: C++
Result: Time_Limit_Exceed
****************************************************************/ //By BLADEVIL
#include <cstdio>
#include <cstring>
#define maxn 1000010
#define LL long long using namespace std; LL n,time,l;
LL other[maxn<<],last[maxn],pre[maxn<<],dfn[maxn],low[maxn],vis[maxn],que[maxn],a[maxn],xx[maxn];
LL ans;
LL len[maxn<<],max1[maxn],max2[maxn],sum[maxn],w[maxn],yy[maxn],maxlen[maxn];
LL save; void getmin(LL &x,LL y)
{if (y<x) x=y;} void connect(LL x,LL y,LL z) {
pre[++l]=last[x];
last[x]=l;
other[l]=y;
len[l]=z;
//if (y>x) printf("%d %d %lld\n",x,y,z);
} void dfs(LL x,LL fa) {
dfn[x]=low[x]=++time;
for (LL q=last[x];q;q=pre[q]) {
if (other[q]==fa) continue;
if (!low[other[q]]) {
dfs(other[q],x);
getmin(low[x],low[other[q]]);
} else getmin(low[x],dfn[other[q]]);
}
if (low[x]!=dfn[x]) save=low[x];
} void dp(LL x) {
memset(que,,sizeof que);
LL h=,t=1ll;
que[]=x; vis[x]=1ll;
while (h<t) {
LL cur=que[++h];
for (LL q=last[cur];q;q=pre[q]) {
if (low[other[q]]==low[x]) continue;
if (vis[other[q]]) continue;
vis[other[q]]=vis[cur]+1ll;
que[++t]=other[q];
}
}
//for (LL i=1;i<=t;i++) printf("%d ",que[i]); printf("\n");
for (LL i=t;i;i--)
for (LL q=last[que[i]];q;q=pre[q]) {
if (low[other[q]]==low[x]) continue;
if (vis[other[q]]!=vis[que[i]]+) continue;
//printf(" %d %d\n",que[i],other[q]);
if (max1[other[q]]+len[q]>max1[que[i]])
max2[que[i]]=max1[que[i]],max1[que[i]]=max1[other[q]]+len[q]; else
if (max1[other[q]]+len[q]>max2[que[i]]) max2[que[i]]=max1[other[q]]+len[q];
if (max1[other[q]]+max2[other[q]]>maxlen[que[i]])
maxlen[que[i]]=max1[other[q]]+max2[other[q]];
if (max1[que[i]]+max2[que[i]]>maxlen[que[i]])
maxlen[que[i]]=max1[que[i]]+max2[que[i]];
if (maxlen[que[i]]<maxlen[other[q]]) maxlen[que[i]]=maxlen[other[q]];
}
//for (LL i=1;i<=t;i++) printf("%d %lld %lld %lld\n",que[i],max1[que[i]],max2[que[i]],maxlen[que[i]]);
} void solve(LL x) {
LL now=0ll;
dfs(x,-);
//printf("%d",save);
if (save)
for (LL i=;i<=n;i++) if (low[i]==save) x=i;
save=;
/*if (xx[xx[x]]==x)
{
ans+=(yy[x]>yy[xx[x]])?yy[x]:yy[xx[x]];
return;
}*/
LL cur;
for (LL i=;i<=n;i++) if (low[i]==low[x]) dp(i),cur=i;
//printf(" %lld\n",max1[x]);
LL t=; a[t]=cur;
while () {
for (LL q=last[a[t]];q;q=pre[q]) {
now=(maxlen[a[t]]>now)?maxlen[a[t]]:now;
if (low[other[q]]!=low[x]) continue;
if (other[q]==a[t-]) continue;
a[++t]=other[q]; sum[t]=len[q]; break;
}
if (a[t]==cur) break;
}
//printf(" %d ",x);
//for (LL i=1;i<=t;i++) printf(" %lld %d %d\n",max1[a[i]],a[i],sum[i]);
t--;
for (LL i=;i<=t;i++) a[i+t]=a[i],sum[i+t]=sum[i];
t*=;
//for (LL i=1;i<=t;i++) printf(" %lld %d %d\n",max1[a[i]],a[i],sum[i]);
for (LL i=;i<=t;i++) sum[i]+=sum[i-];
LL len=t>>1ll;
memset(que,,sizeof que);
LL l=,r=; que[]=;
for (LL i=;i<=t;i++) {
if (i-que[l]+>len) l++;
w[i]=max1[a[que[l]]]+max1[a[i]]+sum[i]-sum[que[l]];
//printf("w[i]=%d",w[i]); printf(" %d %d\n",i,que[l]);
while (l<=r&&(max1[a[i]]-sum[i]>max1[a[que[r]]]-sum[que[r]])) r--;
que[++r]=i;
//for (LL i=l;i<=r;i++) printf("|%d ",que[i]); printf("\n");
}
for (LL i=;i<=t;i++) now=(w[i]>now)?w[i]:now;
//printf(" %lld ",ans);
ans+=now;
} int main() {
scanf("%d",&n);
for (LL i=;i<=n;i++) scanf("%d%lld",&xx[i],&yy[i]);
for (LL i=;i<=n;i++) {
if (xx[i]==i) continue;
if (xx[xx[i]]==i&&xx[i]>i) yy[i]=(yy[xx[i]]>yy[i])?yy[xx[i]]:yy[i],yy[xx[i]]=-1ll;
}
for (LL i=;i<=n;i++) if (yy[i]!=-) connect(i,xx[i],yy[i]),connect(xx[i],i,yy[i]);
for (LL i=;i<=n;i++) if (!low[i]) solve(i);
//for (LL i=1;i<=n;i++) printf(" %d %d %d\n",i,low[i],dfn[i]);
printf("%lld\n",ans);
return ;
}

bzoj 1791 DP的更多相关文章

  1. bzoj 3622 DP + 容斥

    LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...

  2. BZOJ 1791 岛屿(环套树+单调队列DP)

    题目实际上是求环套树森林中每个环套树的直径. 对于环套树的直径,可以先找到这个环套树上面的环.然后把环上的每一点都到达的外向树上的最远距离作为这个点的权值. 那么直径一定就是从环上的某个点开始,某个点 ...

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

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

  4. BZOJ - 1003 DP+最短路

    这道题被马老板毒瘤了一下,TLE到怀疑人生 //然而BZOJ上妥妥地过了(5500ms+ -> 400ms+) 要么SPFA太玄学要么是初始化block被卡到O(n^4) 不管了,不改了 另外D ...

  5. 「BZOJ 1791」「IOI 2008」Island「基环树」

    题意 求基环树森林所有基环树的直径之和 题解 考虑的一个基环树的直径,只会有两种情况,第一种是某个环上结点子树的直径,第二种是从两个环上结点子树内的最深路径,加上环上这两个结点之间的较长路径. 那就找 ...

  6. BZOJ 2431 & DP

    题意:求逆序对数量为k的长度为n的排列的个数 SOL: 显然我们可以对最后一位数字进行讨论,判断其已经产生多少逆序对数量,然后对于前n-1位同样考虑---->每一个长度的排列我们都可以看做是相同 ...

  7. bzoj 1791: [Ioi2008]Island 岛屿

    #include<iostream> #include<cstdio> #define M 1000009 using namespace std; *M],cnt,n,hea ...

  8. 【BZOJ 1791】 [Ioi2008]Island 岛屿

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

  9. bzoj 1592 dp

    就是dp啊 f[i][j]表示到第i位,最后一位高度是j的最小花费 转移::f[i][j]=minn(f[i-1][k])+abs(a[i]-num[j]);(k<=j) #include< ...

随机推荐

  1. 三维网格形变算法(Linear rotation-invariant coordinates和As-Rigid-As-Possible)

    在三维网格形变算法中,个人比较喜欢下面两个算法,算法的效果都比较不错, 不同的是文章[Lipman et al. 2005]算法对控制点平移不太敏感.下面分别介绍这两个算法: 文章[Lipman et ...

  2. 第一次使用Android Studio时你应该知道的一切配置(二):新建一个属于自己的工程并安装Genymotion模拟器

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  3. Android 屏幕适配(一)百分比布局库(percent-support-lib) 解析与扩展

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46695347: 本文出自:[张鸿洋的博客] 一.概述 周末游戏打得过猛,于是周 ...

  4. ES6新增const常量、let变量

    JavaScript 严格模式(use strict) 严格模式下你不能使用未声明的变量. const c1 = 1; const c2 = {}; const c3 = []; 不能对c1的值进行再 ...

  5. 10Mybatis_mybatis和hibernate本质区别和应用场景

    hibernate:是一个标准的ORM框架(对象关系映射).入门门槛较高,不需要程序写sql语句,sql语句自动生产了. 对sql的优化比较困难. 应用场景:适用与需求变化不多的中小型项目中,比如后台 ...

  6. FormsAuthentication详解

    配置安全鉴别 鉴别是指鉴定来访用户是否合法的过程.ASP.NET Framework支持三种鉴别类型: Windows鉴别: NET Passport鉴别: Forms鉴别. 对于某一特定的应用程序, ...

  7. sed 4个功能

    [root@lanny test]# cat test.txt test liyao lanny 经典博文: http://oldboy.blog.51cto.com/2561410/949365 h ...

  8. [原]iBatis.Net(C#)系列一:简介及运行环境

    转载请注明http://www.cnblogs.com/13590/archive/2013/02/27/2934580.html 摘要:介绍iBatis.Net的基本情况和运行原理,运行环境中各参数 ...

  9. sqlalchemy 的 ORM 方式使用示例

    知乎: 使用 sqlalchemy 的 orm 方式操作数据库是一种怎样的体验? 答: 酸爽! 本文基于:win10 + python3.4 + sqlAlchemy 1.0.13 先看一个图(来源) ...

  10. C#操作JSON

    http://www.cnblogs.com/LiZhiW/p/3624729.html C#操作JSON 1. .NET对JSON的支持介绍............................. ...