zoukankan      html  css  js  c++  java
  • 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
    ");
            else
            {
                for(int i =1; i <= n; i++)
                {
                    if(dp[i] == -1)
                    {
                        dfs(i,-1);
    //                    cout <<tans << endl;
                    }
                }
                printf("%d
    ",tans);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    数据的追踪审计
    通知模块设计
    数据库'tempdb' 的事务日志已满处理方法
    三级联动
    组合查询
    用户控件
    MDI容器
    控件说明
    winfrom
    自动生成编号
  • 原文地址:https://www.cnblogs.com/Przz/p/5812360.html
Copyright © 2011-2022 走看看