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;

             }

  • 相关阅读:
    关于项目管理的几点建议
    网站性能优化之服务端(一)
    HP CQ35 Windows7声卡驱动安装不上问题
    ubuntu双系统启动时卡死解决办法
    第十九周练习题
    第十六周作业练习题
    第十七周练习题
    第十八周练习题
    第十五周练习题
    第十四周练习题
  • 原文地址:https://www.cnblogs.com/csgc0131123/p/5290369.html
Copyright © 2011-2022 走看看