zoukankan      html  css  js  c++  java
  • 54.施工方案第二季(最小生成树)


    时间限制: 1 s

     空间限制: 128000 KB

     题目等级 : 黄金 Gold

    题解

     查看运行结果

    题目描述 Description

    c国边防军在边境某处的阵地是由n个地堡组成的。工兵连受命来到阵地要进行两期施工。

    第一期的任务是挖掘暗道让所有地堡互联互通。现已勘测设计了m条互不相交的暗道挖掘方案,如果这m条暗道都实施挖掘,肯定能达到互联互通的目的。事实上,适当选择其中n-1个方案挖掘,就能实现互联互通,即从每个地堡出发都能到达其他任何一个地堡(允许经过别的地堡)。

    连长精心谋算,在m个设计规划中选取了挖掘总距离最短且能保证互联互通的若干个暗道规划实施了挖掘,完成了第一期的施工任务后又接受了第二期的施工任务,要求选择一个地堡进行扩建改造,使其能向每个地堡提供弹药。为了让弹药供应更及时、更快捷,从改扩建的地堡到最远地堡的距离(称为最远输送距离)应当尽量小。

    你的任务是先求出第一期施工挖掘的总距离,再求改扩建地堡最远输送距离的最小值。

    输入描述 Input Description

    其中第一行是nmm>=n
    下面的m行每行3个数xiyizi,表示xiyi的距离是zi
      zi<1000000
    m个距离互不相等

    输出描述 Output Description

    共包含两行,每行一个整数,
    第一行是第一期的挖掘总距离,第二行是最远输送距离的最小值。

    样例输入 Sample Input

    5
    1
    2
    3
    4
    5

    样例输出 Sample Output

    6
    3

    数据范围及提示 Data Size & Hint

    【样例说明】
    第一期挖掘1223343条暗道,第二期选择3号地堡进行改扩建,最远输送距离是3
    【数据规模】
    60%
    的数据 n<10m<20
    80%
    的数据 n<1000m<2000
    100%
    的数据 n<100000m<200000

    错误代码:(总距离正确)

    #include

    using namespace std;

    #include

    #include

    #include

    #include

    #include

    #define maxn 100000

    #define maxm 200000

    struct Edge{

           int u,v,next;

           long long w;

    };

    Edge edge[2*maxm];

    long long tot=0;

    int visit[maxn]={0},head[maxn],man[maxn];

    int maxdis[maxn],n,m;

    void input();

    void prim();

    int main()

    {

           input();

           prim();

           printf("%lld ",tot);

           for(int i=2;i<=n;++i)

           {

                  if(maxdis[i]!=0&&maxdis[i]

                   maxdis[1]=maxdis[i];

           }

           printf("%d ",maxdis[1]);

           return 0;

    }

    void input()

    {

           memset(maxdis,0,sizeof(maxdis));

           int a,b;

           long long c;

           head[1]=0;

           scanf("%d%d",&n,&m);

           for(int i=1;i<=m;++i)

           {

                  scanf("%d%d%d",&a,&b,&c);

                  edge[i].u=a;edge[i].v=b;

                  edge[i].w=c;

                  edge[i].next=head[a];

                  head[a]=i;

                  if(c>maxdis[a])

                  maxdis[a]=c;

                  edge[i+m].v=a;edge[i+m].u=b;

                  edge[i+m].w=c;

                  edge[i+m].next=head[b];

                  head[b]=i+m;

                  if(c>maxdis[b])

                  maxdis[b]=c;

           }

    }

    void prim()

    {

           memset(man,99,sizeof(man));

           man[1]=0;

           int k=1;

           visit[k]=1;

           tot+=man[k];

           for(int i=2;i<=n-1;++i)

           {

                  int minxx=999999;

                  for(int j=1;j<=n;++j)

                  {

                         if(!visit[j]&&man[j]

                         {

                                minxx=man[j];

                                k=j;

                         }

                  }

                  visit[k]=1;

                  tot+=man[k];

                  for(int j=head[k];j!=0;j=edge[j].next)

                  {

                         if(!visit[edge[j].v]&&edge[j].w

                         {

                                man[edge[i].v]=edge[j].w;

                               

                         }

                        

                  }

           }

    }

    正确:

    #include

    #include

    #include

    #include

    #include

    #define maxn 100005

    #define INF 0x7fffffff

     

    long long cnt,head[maxn],fa[maxn],vis[maxn],down[maxn][2],up[maxn],dis[maxn];

    int n,m;

    struct node

       {

          int to;

          int next;

          int edge;

       }e[maxn<<2];

     

    struct ss

       {

         int x,y,z;

       }a[maxn];

     

    using namespace std;

     

    void insert(int u,int v,int edge)

        {

         e[++cnt].to=v;

         e[cnt].edge=edge;

         e[cnt].next=head[u];

         head[u]=cnt;

           }

     

    int find(int x)

       {

          if (fa[x]==x) return x;

          fa[x]=find(fa[x]);

          return fa[x];

       }

      

    bool cmp(ss a,ss b)  

        {

               return a.z

           }

          

    void dfs1(int rt)

       {

          vis[rt]=1;

          for (int i=head[rt];i;i=e[i].next)

            {

              if (!vis[e[i].to]) dfs1(e[i].to);

                  else continue;

              if (down[e[i].to][0]+e[i].edge>down[rt][0])

                      {

                        down[rt][1]=down[rt][0];

                           down[rt][0]=down[e[i].to][0]+e[i].edge; 

                       

                      else if (down[e[i].to][0]+e[i].edge>down[rt][1])

                           down[rt][1]=down[e[i].to][0]+e[i].edge;

                  

        }

          

    void dfs2(int rt,int fat,int val)

        {

          vis[rt]=1;   

          long long tmp=0;      

          if (rt==1) up[rt]=0;

                else

                     {

                        up[rt]=up[fat]+val;

                       if (down[fat][0]==down[rt][0]+val) tmp=down[fat][1]+val;

                             else tmp=down[fat][0]+val;

                          up[rt]=max(up[rt],tmp);            

                     }

             dis[rt]=max(up[rt],down[rt][0]);

             for (int i=head[rt];i;i=e[i].next)

                 if (!vis[e[i].to]) dfs2(e[i].to,rt,e[i].edge);     

             

          

    int main()

       {

          scanf("%d%d",&n,&m);

          long long ans2=INF;

          for (int i=1;i<=m;i++)

            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);

          sort(a+1,a+m+1,cmp);

          for (int i=1;i<=n;i++) fa[i]=i;

          int k=0,ans=0;

          for (int i=1;i<=m;i++)

              {

                   int fa1=find(a[i].x),fa2=find(a[i].y);

                   if (fa1==fa2) continue;

                   fa[fa2]=fa1;

                   insert(a[i].x,a[i].y,a[i].z);

                   insert(a[i].y,a[i].x,a[i].z);

                   k++;

                   ans+=a[i].z;

                   if (k==n-1) break;

                         }

         printf("%lld ",ans);

            memset(vis,0,sizeof(vis));

            dfs1(1);

            memset(vis,0,sizeof(vis));

            dfs2(1,0,0);

            for (int i=1;i<=n;i++)

               ans2=min(ans2,dis[i]);

            printf("%lld",ans2);                            

            return 0;

             }

  • 相关阅读:
    解决maven update project 后项目jdk变成1.5的问题
    applicationContext-common.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal
    SQL0668N 不允许对表"xxx"执行操作,原因码为 "1"
    maven下的jar项目打包的方法
    spring security 4.2后出现CouldnotverifytheprovidedCSRFtokenbecauseyoursessionwasnotfound
    maven-javadoc-plugin 出现错误Unsupported major.minor version 51.0
    通过 Spring Security配置 解决X-Frame-Options deny 造成的页面空白 iframe调用问题
    yaml模块
    centos 下 yum安装python3
    Python 之ConfigParser模块
  • 原文地址:https://www.cnblogs.com/csgc0131123/p/5290369.html
Copyright © 2011-2022 走看看