zoukankan      html  css  js  c++  java
  • 刷题总结——湫湫系列故事——设计风景线(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;
    }
  • 相关阅读:
    windows服务的默认启动类型和登录帐户
    oracle通过sql随机取表中的10条记录
    oracle如何四舍五入?
    Sql Server数据库自增长字段标识列的插入或更新修改操作办法
    将一个表中的数据导入到另一张表中
    设计模式已经陨落了?
    LINQ架构简单描述
    Asp.Net 验证控件
    .Net 三层架构开发初步
    C++编程思想
  • 原文地址:https://www.cnblogs.com/AseanA/p/7719164.html
Copyright © 2011-2022 走看看