随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
现在已经勘探确定了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
这可能是个非连通图,当时没考虑到,所以一直wrong answer
先用并查集求其是否有环,有环直接输出YES
求一个连通图里最长的路径,先从任意一点出发,求其最长路径a,然后从最长路径端点出发,再求最长路径b,b就是该连通图的最长路径.
AC:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxn 100007
using namespace std;
int vis[maxn],f[maxn],flag,n,m,x,z,maxi,maxs,ans;
int vis2[maxn];
struct node{
int y,w;
};
vector<node> q[maxn];
int find(int x)
{
if(f[x]!=x)
f[x]=find(f[x]);
return f[x];
}
void mix(int a,int b)
{
int fx=find(a),fy=find(b);
if(fx!=fy)
f[fx]=fy;
else flag=1;
}
void dfs(int x,int sum)
{
vis[x]=1;
vis2[x]=1;
if(sum>maxs)
maxs=sum,maxi=x;
for(int i=0;i<q[x].size();i++)
if(!vis[q[x][i].y])
dfs(q[x][i].y,sum+q[x][i].w);
return ;
}
int main()
{
int a,b,d;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
{
f[i]=i;
q[i].clear();
}
flag=0;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&d);
mix(a,b);
node e;
e.y=b,e.w=d;
q[a].push_back(e);
e.y=a;
q[b].push_back(e);
}
if(flag)
{
printf("YES\n");
continue;
}
memset(vis2,0,sizeof(vis2));
ans=0;
for(int i=1;i<=n;i++)//对于非连通图需要分别求最长路径
{
if(!vis2[i])
{
maxs=maxi=0;
memset(vis,0,sizeof(vis));
dfs(i,0);
memset(vis,0,sizeof(vis));
maxs=0;
dfs(maxi,0);
if(maxs>ans)
ans=maxs;
}
}
printf("%d\n",ans);
}
return 0;
}
还可以用树形dp来解决