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

题目链接:https://vjudge.net/problem/HDU-4514

  随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。 
  现在已经勘探确定了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

思路:首先先判环,如果有环直接输出,可以用并查集判环或者dfs,接下来就是求树的最大直径,这个题容易超内存,用邻接表+结构体存边、权。AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
struct node{
    int v,w;
    node(int _v, int _w) : v(_v), w(_w) {}
};
vector<node>e[100001];
int n,m,fa[100001],dp[100001],ans;
int find(int x){
    if(x!=fa[x]) fa[x]=find(fa[x]);
    return fa[x];
}
void dfs(int u,int father){
    int maxx=0;
    for(int i=0;i<e[u].size();i++)
    {
        int v=e[u][i].v;
        int w=e[u][i].w;
        if(v==father) continue;
        dfs(v,u);
        ans=max(ans,dp[v]+maxx+w);
        maxx=max(maxx,dp[v]+w);
    }
    dp[u]=maxx;
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        bool flag=false;
        ans=0;
        for(int i=1;i<=n;i++)
            fa[i]=i,dp[i]=-1,e[i].clear();
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            e[x].push_back(node(y,z));
            e[y].push_back(node(x,z));
            if(flag) continue;
            int fx,fy;
            fx=find(x),fy=find(y);
            if(fx!=fy) fa[fx]=fy;
            else flag=true;
        }
        if(flag){  printf("YES\n");continue; }
        for(int i=1;i<=n;i++)   //找根
      	 	if(dp[i]==-1) dfs(i,-1);
    	printf("%d\n",ans);
    }
}

 超空间代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<vector>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=101000; //超空间
 7 vector<int>son[maxn];
 8 int dp[maxn][2],map[maxn][maxn],ans;
 9 int fa[maxn];
10 int find(int x)
11 {
12     if(fa[x]!=x) fa[x]=find(fa[x]);
13     return fa[x];
14 }
15 void DFS(int u,int fa){
16     for(int i=0;i<son[u].size();i++){
17         int v=son[u][i];
18         if(v!=fa)
19         {
20             DFS(v,u);
21             int w=map[u][v]+dp[v][0];
22             if(w>dp[u][0]){
23                 dp[u][1]=dp[u][0];
24                 dp[u][0]=w;
25             }
26             else if(w>dp[u][1])
27             dp[u][1]=w;
28         }
29     }
30     ans=max(ans,dp[u][0]+dp[u][1]);
31 }
32 int main(){
33        int u,v,w,n,m;
34        while(~scanf("%d%d",&n,&m))
35        {
36             memset(dp,0,sizeof(dp));
37          memset(map,0,sizeof(map));
38          for(int i=0;i<maxn;i++) fa[i]=i;
39          bool flag=false;
40            for(int i=1;i<=m;i++)
41            {
42                    scanf("%d%d%d",&u,&v,&w);
43                    son[u].push_back(v);
44                 son[v].push_back(u);
45                 map[v][u]=w;
46                 map[u][v]=w;
47                 int x=find(u);
48                 int y=find(v);
49                 if(x!=y) fa[x]=v;
50                 else flag=true;
51            }
52            if(flag==true)
53            {
54                    printf("YES\n");
55                    continue;
56            }
57             ans=0;
58             DFS(1,0);
59             printf("%d\n",ans);
60             for(int i=0;i<maxn;i++)
61             son[i].clear();
62         }
63 }  

原文地址:https://www.cnblogs.com/djh0709/p/9601076.html

时间: 2024-10-11 00:55:44

HDU - 4514 湫湫系列故事——设计风景线(并查集判环+树形DP)的相关文章

HDU4514湫湫系列故事——设计风景线(并查集判环+最长直径)

题目链接:传送门 题意: 先判一个图是否存在换,不存在的话输出这个图的最长路径. 代码如下: #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <queue> using namespace std; const int maxn = 1e6+10; int par[maxn/10],head[maxn/10]; bool

HDU 4514 湫湫系列故事——设计风景线(并查集+树形DP)

湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 4669    Accepted Submission(s): 853 Problem Description 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形

hdu-----(4514)湫湫系列故事——设计风景线(树形DP+并查集)

湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3105    Accepted Submission(s): 562 Problem Description 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,

HDU - 4514 湫湫系列故事――设计风景线

Description 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度.请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少? 其中,可以兴建的路线均是双向的,他们之间的长度均大于0. Input 测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描

hdu 4514 湫湫系列故事――设计风景线(求树的直径)

随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好.  现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度.请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?  其中,可以兴建的路线均是双向的,他们之间的长度均大于0. Input 测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述:  接下去m行,

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

题目: 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度.请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少? 其中,可以兴建的路线均是双向的,他们之间的长度均大于0. 思路: 将给出的边的两个端点用并查集放在一起,如果这两个点的祖先相等说明构成了一个环. 在这个用并查

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

题意:略. 析:首先先判环,如果有环直接输出,用并查集就好,如果没有环,那么就是一棵树,然后最长的就是树的直径,这个题注意少开内存,容易超内存, 还有用C++交用的少一些,我用G++交的卡在32764K,限制是32768K.. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib&

HDU ACM 4514 湫湫系列故事——设计风景线-&gt;树上环的判断+树上最长路

题意:一个无向图,首先判定是否成环,然后求一条最长链. 分析:成环用并查集判断,最长链就是树形dp了. #include<iostream> #include<vector> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define N 100005 int ans; int dp[N]; //dp[i]表示i节点为根节点树的最长路 int p[N];

hdu 4502 吉哥系列故事——临时工计划

吉哥系列故事--临时工计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 2921    Accepted Submission(s): 1128 Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要