hdu 4514 并查集+树形dp
Posted Przz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 4514 并查集+树形dp相关的知识,希望对你有一定的参考价值。
湫湫系列故事——设计风景线
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 4539 Accepted Submission(s): 816
Problem Description
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?
其中,可以兴建的路线均是双向的,他们之间的长度均大于0。
现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?
其中,可以兴建的路线均是双向的,他们之间的长度均大于0。
Input
测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述;
接下去m行,每行3个数字u v w,分别代表这条线路的起点,终点和长度。
[Technical Specification]
1. n<=100000
2. m <= 1000000
3. 1<= u, v <= n
4. w <= 1000
接下去m行,每行3个数字u v w,分别代表这条线路的起点,终点和长度。
[Technical Specification]
1. n<=100000
2. m <= 1000000
3. 1<= u, v <= n
4. w <= 1000
Output
对于每组测试数据,如果能够建成环形(并不需要连接上去全部的风景点),那么输出YES,否则输出最长的长度,每组数据输出一行。
Sample Input
3 3
1 2 1
2 3 1
3 1 1
Sample Output
YES
/* hdu 4514 并查集+树形dp problem: 给你一个图,如果其中有环,则输出YES. 否则输出其中最长链的长度 solve: 通过并查集可以判断是否有环. 树形dp计算经过当前节点最长链的长度. hhh-2016-08-24 21:02:37 */ #pragma comment(linker,"/STACK:124000000,124000000") #include <algorithm> #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <vector> #include <math.h> #include <queue> #include <map> #define lson i<<1 #define rson i<<1|1 #define ll long long #define clr(a,b) memset(a,b,sizeof(a)) #define scanfi(a) scanf("%d",&a) #define scanfl(a) scanf("%I64d",&a) #define key_val ch[ch[root][1]][0] #define inf 0x3f3f3f3f #define mod 1000003 using namespace std; const int maxn = 100010; int fa[maxn]; int head[maxn]; int dp[maxn]; int tot ; void ini() { tot = 0; memset(head,-1,sizeof(head)); memset(fa,-1,sizeof(fa)); memset(dp,-1,sizeof(dp)); } struct node { int to,w,next; } edge[maxn*20]; void add_edge(int u,int v,int w) { edge[tot].to = v,edge[tot].w = w,edge[tot].next = head[u],head[u] = tot ++; } int fin(int x) { if(fa[x] == -1) return x; return fa[x] = fin(fa[x]); } int tans = 0; int dfs(int now,int far) { int tnex = 0; for(int i = head[now]; ~i; i = edge[i].next) { int v = edge[i].to; if(v == far) continue; int re = dfs(v,now); tans = max(tans,tnex+re +edge[i].w); tnex = max(tnex,re + edge[i].w); } return dp[now] = tnex; } int main() { int n,m; int u,v,w; // freopen("in.txt","r",stdin); while(scanfi(n) != EOF) { scanfi(m); ini(); int flag =0 ; for(int i = 1; i <= m; i++) { scanfi(u),scanfi(v),scanfi(w); add_edge(u,v,w); add_edge(v,u,w); int ta = fin(u); int tb = fin(v); if(ta == tb) flag = 1; else fa[ta] = tb; } tans = 0; if(flag) printf("YES\n"); else { for(int i =1; i <= n; i++) { if(dp[i] == -1) { dfs(i,-1); // cout <<tans << endl; } } printf("%d\n",tans); } } return 0; }
以上是关于hdu 4514 并查集+树形dp的主要内容,如果未能解决你的问题,请参考以下文章
HDU - 4514 湫湫系列故事——设计风景线(并查集判环+树形DP)