BZOJ 2657: [Zjoi2012]旅游(journey)【树DP找树的直径】

最开始没看懂题…

看了这篇题解后才懂题…

https://blog.csdn.net/Clove_unique/article/details/53004733

将每个三角形看成点然后相邻的话就连边于是就得到一棵树,答案显然就是树的直径

#include 
using namespace std;
const int N=6e5+5;
const int Inf=1e18;
int n,ans,cnt,f[N],g[N];
int inc,to[N],nxt[N],head[N];
struct node {
	int x,y,id;
}a[N];
void swp(int &x,int &y) {
	int ret=x;x=y;y=ret;
}
void ins(int x,int y) {
	to[++inc]=y;nxt[inc]=head[x];head[x]=inc;
}
void dp(int x,int fa) {
	for(int i=head[x];i;i=nxt[i]) {
		int y=to[i];
		if(y!=fa) {
			dp(y,x);
			if (f[y]+1>f[x]) g[x]=f[x],f[x]=f[y]+1;
			else g[x]=max(g[x],f[y]+1);
		}
	}
	ans=max(ans,f[x]+g[x]);
}
bool cmp(node p,node q) {
	return p.xy) swp(x,y);
        if(y>z) swp(y,z);
        if(x>y) swp(x,y);
        a[++cnt].x=x,a[cnt].y=y,a[cnt].id=i;
        a[++cnt].x=y,a[cnt].y=z,a[cnt].id=i;
        a[++cnt].x=x,a[cnt].y=z,a[cnt].id=i;
	}
	sort(a+1,a+1+cnt,cmp);
	for(int i=1;i<=cnt;i++) if(a[i].x==a[i-1].x&&a[i].y==a[i-1].y) ins(a[i].id,a[i-1].id),ins(a[i-1].id,a[i].id);
	dp(1,0);printf("%d",ans+1);
	return 0;
}

你可能感兴趣的:(BZOJ,动态规划-树形DP,动态规划与递推)