欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 编程资源 > 编程问答 >内容正文

编程问答

54.施工方案第二季(最小生成树) -凯发k8官方网

发布时间:2023/11/29 编程问答 24 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 54.施工方案第二季(最小生成树) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.


时间限制: 1 s

 空间限制: 128000 kb

 题目等级 : 黄金 gold

题解

 查看运行结果

题目描述 description

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

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

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

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

输入描述 input description

其中第一行是n和m,m>=n
下面的m行每行3个数xi、yi、zi,表示xi到yi的距离是zi
  zi<1000000且m个距离互不相等

输出描述 output description

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

样例输入 sample input

4 5
1 2 1
2 3 2
3 4 3
4 1 4
3 1 5

样例输出 sample output

6
3

数据范围及提示 data size & hint

【样例说明】
第一期挖掘1到2、2到3和3到4的3条暗道,第二期选择3号地堡进行改扩建,最远输送距离是3
【数据规模】
60%的数据 n<10且m<20
80%的数据 n<1000且m<2000
100%的数据 n<100000且m<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\n",tot);

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

       {

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

               maxdis[1]=maxdis[i];

       }

       printf("%d\n",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\n",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;

         }

转载于:https://www.cnblogs.com/c1299401227/p/5370766.html

总结

以上是凯发k8官方网为你收集整理的54.施工方案第二季(最小生成树)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图