湫湫系列故事——设计风景线
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 4248 Accepted Submission(s): 741
Problem Description
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
现在已经勘探确定了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
接下去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
Source
Recommend
liuyiding
还是求树的直径,在求直径前要判断一下是否成环(用并查集)
还要注意一点是,这些边组成的树可能不止一个!所以不能只查一次直径。要把所有的树的直径都查一遍,然后选出最大的那个。
求树的直径还是相同的模板。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define N 100000+10
int per[N],vis[N],dis[N],head[N];
struct a
{
int t,w,next;
}edge[2000000+10];
int Find(int x)
{
int r=x;
while(r!=per[r])
r=per[r];
int i=x,j;
while(i!=r)
{
j=per[i];
per[i]=r;
i=j;
}
return r;
}
int Judge(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
per[fx]=fy;
return 0;
}
return 1;
}
int edgenum,Tnode;
int ans;
void addedge(int u,int v,int w)
{
edge[edgenum].t=v;
edge[edgenum].w=w;
edge[edgenum].next=head[u];
head[u]=edgenum++;
}
void bfs(int s)
{
int i,u,v;
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
queue<int> q;
vis[s]=1;dis[s]=0;ans=0;
q.push(s);
while(!q.empty())
{
u=q.front();
q.pop();
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].t;
if(!vis[v])
{
if(dis[v]<dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
if(ans<dis[v])
{
ans=dis[v];
Tnode=v;
}
}
vis[v]=1;
q.push(v);
}
}
}
}
int main()
{
int i,n,m;
int x,y,w;
while(~scanf("%d%d",&n,&m))
{
int flag=0;
memset(head,-1,sizeof(head));
edgenum=0;
for(i=1;i<=n;i++)
per[i]=i;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&w);
if(Judge(x,y))
flag=1;
addedge(x,y,w);
addedge(y,x,w);
}
if(flag)
printf("YES\n");
else
{
int maxx=0;
for(i=1;i<=n;i++)
{
if(per[i]==i)
{
bfs(i);
bfs(Tnode);
maxx=max(maxx,ans);
}
}
printf("%d\n",maxx);
}
}
return 0;
}