刷题总结——湫湫系列故事——设计风景线(hdu4514 并差集判环+树的直径)

题目:

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

题解

  模板题不多说···主要是做这道题时给我的一个惨痛教训···我‘读入剪枝’了,也就是判环的时候发现环直接break掉了··导致一直没找出来···

代码:

  

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+500;
const int M=1e6+500;
int tot,fst[N],nxt[M*2],go[M*2],val[M*2],n,m,father[N],dis1,p1,dis2,ans;
bool visit[N];
inline int getfa(int a)
{
  if(father[a]==a)  return a;
  else return father[a]=getfa(father[a]);
}
inline int R()
{
  char c;int f=0;
  for(c=getchar();c<'0'||c>'9';c=getchar());
  for(;c<='9'&&c>='0';c=getchar())  f=(f<<3)+(f<<1)+c-'0';
  return f;
}
inline void comb(int a,int b,int c)
{
  nxt[++tot]=fst[a],fst[a]=tot,go[tot]=b,val[tot]=c;
  nxt[++tot]=fst[b],fst[b]=tot,go[tot]=a,val[tot]=c;
}
inline void dfs1(int u,int fa,int len)
{
  visit[u]=true;
  if(len>dis1){dis1=len,p1=u;}
  for(int e=fst[u];e;e=nxt[e])
  {
    int v=go[e];if(v==fa)  continue;
    dfs1(v,u,len+val[e]);
  }
}
inline void dfs2(int u,int fa,int len)
{
  if(len>dis2) dis2=len;
  for(int e=fst[u];e;e=nxt[e])
  {
    int v=go[e];if(v==fa)  continue;
    dfs2(v,u,len+val[e]);
  }
}
int main()
{
  while(~scanf("%d%d",&n,&m))
  {
    int a,b,c;memset(fst,0,sizeof(fst));memset(visit,false,sizeof(visit));
    tot=0;bool flag=false;ans=0;
    for(int i=1;i<=n;i++)  father[i]=i;
    for(int i=1;i<=m;i++)  
    {
      a=R(),b=R(),c=R();comb(a,b,c);
      if(flag==true)  continue;
      int fa=getfa(a),fb=getfa(b);
      if(fa==fb){cout<<"YES"<<"
";flag=true;}
      father[fa]=fb;
    }
    if(flag)  continue;
    for(int i=1;i<=n;i++)
    {  
      if(!visit[i])
      {  
        dis1=0,p1=0,dis2=0;
        dfs1(i,0,0);dfs2(p1,0,0);ans=max(ans,dis2);
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}
原文地址:https://www.cnblogs.com/AseanA/p/7719164.html