zoukankan      html  css  js  c++  java
  • 「LOJ#10068」「一本通 3.1 练习 3」秘密的牛奶运输(次小生成树

    题目描述

    Farmer John 要把他的牛奶运输到各个销售点。运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点。 运输的总距离越小,运输的成本也就越低。低成本的运输是 Farmer John 所希望的。不过,他并不想让他的竞争对手知道他具体的运输方案,所以他希望采用费用第二小的运输方案而不是最小的。现在请你帮忙找到该运输方案。

    输入格式

    第一行是两个整数 N,MN,MN,M,表示顶点数和边数;

    接下来 MMM 行每行 333 个整数,x,y,zx,y,zx,y,z,表示一条路的两端 x,yx,yx,y 和距离 zzz

    输出格式

    仅一行,输出第二小方案。

    样例

    样例输入

    4 4
    1 2 100
    2 4 200
    2 3 250
    3 4 100

    样例输出

    450

    数据范围与提示

    对于全部数据,1≤N≤500,1≤M≤104,1≤z≤1091le Nle 500,1le Mle 10^4,1le zle 10^91N500,1M104,1z109,数据可能有重边。

    题解

    这是一道裸的次小生成树。

    次小生成树的两种食用方法:

    • 就叫它法一吧。
      • 首先求个最小生成树。
      • 然后每次删掉一条树边,求树边两端两点的最短路。
      • 时间复杂度$O(nmlogm)$
    • 就叫它法二吧。
      • 也是首先求个最小生成树。
      • 之后求树上每两点的路径间最大的边权,需要$O(n^2)$。(枚举每个点做根,然后$O(n)$遍历
      • 然后枚举每个非树边,设端点为$i,j$。
      • 那么如果把这条边接上生成树,那么就把它所在的环上边权最大的那条边断掉,就是接上这条边的最优解。
      • 所以枚举每条边,维护$最小生成树的权值和-MAX[i][j]+a[i][j]$的最小值。
      • 复杂度$O(n^2+m)$

    然后这里写的是法二。

     1 编号    题目    状态    分数    总时间    内存    代码 / 答案文件    提交者    提交时间
     2 #240021    #10068. 「一本通 3.1 练习 3」秘密的牛奶运输 Accepted    100    74 ms    1404 KiB    C++ / 1.3 K    qwerta    2018-10-22 20:33:11
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdio>
     6 using namespace std;
     7 struct emm{
     8     int l,r,v,tag;
     9 }a[10003];
    10 bool cmp(emm qaq,emm qwq){
    11     return qaq.v<qwq.v;
    12 }
    13 int fa[503];
    14 int fifa(int x)
    15 {
    16     if(fa[x]==x)return x;
    17     return fa[x]=fifa(fa[x]);
    18 }
    19 struct ahh{
    20     int e,f,v;
    21 }b[1003];
    22 int h[503];
    23 int cnt=0;
    24 void con(int x,int y,int len)//加边
    25 {
    26     b[++cnt].f=h[x];
    27     h[x]=cnt;
    28     b[cnt].e=y;
    29     b[cnt].v=len;
    30     b[++cnt].f=h[y];
    31     h[y]=cnt;
    32     b[cnt].e=x;
    33     b[cnt].v=len;
    34     return;
    35 }
    36 int MAX[503][503];//两点树上路径中边权最大值
    37 int s;
    38 void dfs(int x)//dfs找MAX[s][x]
    39 {
    40     for(int i=h[x];i;i=b[i].f)
    41     if(!MAX[s][b[i].e]&&b[i].e!=s)
    42     {
    43         MAX[s][b[i].e]=max(MAX[s][x],b[i].v);
    44         dfs(b[i].e);
    45     }
    46     return;
    47 }
    48 int main()
    49 {
    50     //freopen("a.in","r",stdin);
    51     int n,m;
    52     scanf("%d%d",&n,&m);
    53     for(int i=1;i<=m;++i)
    54     {
    55         int x,y,z;
    56         scanf("%d%d%d",&x,&y,&z);
    57         a[i]=(emm){x,y,z};//建原图
    58     }
    59         //跑最小生成树
    60     for(int i=1;i<=n;++i)
    61       fa[i]=i;
    62     sort(a+1,a+m+1,cmp);
    63     int k=n-1,i=0;
    64     long long now=0;//记录最小生成树的边权和
    65     while(k)
    66     {
    67         ++i;
    68         int u=fifa(a[i].l),v=fifa(a[i].r);
    69         if(u!=v)
    70         {
    71             fa[u]=v;
    72             con(a[i].l,a[i].r,a[i].v);//建树图
    73             k--;
    74             now+=a[i].v;
    75             a[i].tag=1;//标记为树边
    76         }
    77     }
    78     for(s=1;s<=n;++s)
    79     {
    80         dfs(s);
    81     }
    82     long long ans=1e15;
    83     for(int i=1;i<=m;++i)
    84     if(!a[i].tag&&a[i].v>MAX[a[i].l][a[i].r])//如果该边为非树边并且它的权值大于左右端点的树上距离(因为是次小生成树,所以权值要比最小生成树大
    85     {
    86         ans=min(ans,now-MAX[a[i].l][a[i].r]+a[i].v);//把路径上最大的换成这条边的答案
    87     }
    88     cout<<ans;
    89     return 0;
    90 }

    题目描述

    Farmer John 要把他的牛奶运输到各个销售点。运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点。 运输的总距离越小,运输的成本也就越低。低成本的运输是 Farmer John 所希望的。不过,他并不想让他的竞争对手知道他具体的运输方案,所以他希望采用费用第二小的运输方案而不是最小的。现在请你帮忙找到该运输方案。

    输入格式

    第一行是两个整数 N,MN,MN,M,表示顶点数和边数;

    接下来 MMM 行每行 333 个整数,x,y,zx,y,zx,y,z,表示一条路的两端 x,yx,yx,y 和距离 zzz

    输出格式

    仅一行,输出第二小方案。

    样例

    样例输入

    4 4
    1 2 100
    2 4 200
    2 3 250
    3 4 100

    样例输出

    450

    数据范围与提示

    对于全部数据,1≤N≤500,1≤M≤104,1≤z≤1091le Nle 500,1le Mle 10^4,1le zle 10^91N500,1M104,1z109,数据可能有重边。

  • 相关阅读:
    PhoneApplicationPage 之观察 触摸事件 GIS
    读书笔记 之 image GIS
    button 样式 GIS
    TextBlock GIS
    textgame GIS
    c#对List或ListArray或string组数 用linq进行分组统计
    彗星撞地球 怀念下Warez组织的经典力作(15G动画压缩成64Kb的那个)
    .NET Framework各版本独立下载.NET Framework 3.5下载.NET Framework 2.0下载
    asp.net 导出excel 表之后 按钮 页面控件失效不可用,没反应的解决办法。
    SQL Sever 各版本下载 SQL Server 2012下载SQL Server 2008下载SQL Server 2005 下载SQL Server 2000 下载
  • 原文地址:https://www.cnblogs.com/qwerta/p/9833283.html
Copyright © 2011-2022 走看看