题目链接:https://vjudge.net/problem/HDU-4514
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
现在已经勘探确定了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
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);
}
}
超空间代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }