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。
 

 

Input
  测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述;
  接下去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)

HDU 4514 湫湫系列故事――设计风景线 (树形DP)

hdu 4514(树的直径+并查集)

求树的直径+并查集(bfs,dfs都可以)hdu4514

HDU - 4514 湫湫系列故事——设计风景线(并查集判环)

[bzoj2443][Usaco2011 Open]奇数度数_树形dp_生成树_并查集