LOJ10068 秘密的牛奶运输

LOJ10068秘密的牛奶运输

题目描述

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

输入格式

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

接下来 M 行每行 3 个整数,x,y,z,表示一条路的两端x,y 和距离z。

输出格式

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

样例

样例输入

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

样例输出

450

数据范围与提示

对于全部数据,1N500,1M10^4,1z10^9,数据可能有重边。

__________________________________________________________________

严格次小生成树。

ff[i][j]表示:i点向上跳2^j步经过的最大值

fs[i][j]表示:i点向上跳2^j步经过的次大值

这个样枚举每一条边,替换边的两点(u,v)之间在树上的链的最大值或次大值(如果边的权和最大值的权相等),求得的就可能是次小生成树。在所有可能的次小生成树中求最小的就是结果。

__________________________________________________________________

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=505;
  4 const int maxm=1e4+10;
  5 int n,m;
  6 struct edge
  7 {
  8     int u,v,w,nxt;
  9 }e[maxn<<1],ee[maxm];
 10 int head[maxn],js,jss;
 11 long long ans=1000000000000000ll,tt;
 12 void addageint u,int v,int w)
 13 {
 14     e[++js].u=u;e[js].v=v;e[js].w=w;
 15     e[js].nxt=head[u];head[u]=js;
 16 }
 17 void addagefint u,int v,int w)
 18 {
 19     ee[jss].u=u;ee[jss].v=v;ee[jss++].w=w;
 20 }
 21 bool cmpedge a,edge b)
 22 {
 23     return a.w<b.w;
 24 }
 25 int fa[maxn];
 26 int findint x)
 27 {
 28     return fa[x]==x?x:fa[x]=findfa[x]);
 29 }
 30 int f[maxn][10],ff[maxn][10],fs[maxn][10],dep[maxn];
 31 void dfsint u,int fat)
 32 {
 33     dep[u]=dep[fat]+1;
 34     forint i=head[u];i;i=e[i].nxt)
 35     {
 36         int v=e[i].v;
 37         ifv!=fat)
 38         {
 39             f[v][0]=u;
 40             ff[v][0]=e[i].w;
 41             forint i=1;i<10;++i)
 42             {
 43                 f[v][i]=f[f[v][i-1]][i-1];
 44                 int a=ff[v][i-1],b=ff[f[v][i-1]][i-1],c=fs[v][i-1],d=fs[f[v][i-1]][i-1];
 45                 ff[v][i]=maxa,b);
 46                 ifa==b)fs[v][i]=maxc,d);
 47                 else ifa>b)fs[v][i]=maxb,c);
 48                 else fs[v][i]=maxa,d);
 49             }
 50             dfsv,u);
 51         }
 52     }
 53 }
 54 int lg[maxn];
 55 int lcaint u,int v)
 56 {
 57     lg[0]=-1;
 58     forint i=1;i<=n;++i)lg[i]=lg[i>>1]+1;
 59     ifdep[u]<dep[v])swapu,v);
 60     whiledep[u]>dep[v])u=f[u][lg[dep[u]-dep[v]]];
 61     ifu==v)return u;
 62     forint i=lg[dep[u]];i>=0;--i)
 63         iff[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
 64     return f[u][0];
 65 }
 66 void workint u,int l,int &mx,int &se)
 67 {
 68     whiledep[u]>dep[l])
 69     {
 70         int a=ff[u][lg[dep[u]-dep[l]]],c=fs[u][lg[dep[u]-dep[l]]];
 71         u=f[u][lg[dep[u]-dep[l]]];
 72         int b=mx,d=se;
 73         mx=maxa,b);
 74         ifa==b)se=maxc,d);
 75         else ifa>b)se=maxb,c);
 76         else se=maxa,d);
 77     }
 78 }
 79 int main)
 80 {
 81     scanf"%d%d",&n,&m);
 82     forint u,v,w,i=0;i<m;++i)
 83     {
 84         scanf"%d%d%d",&u,&v,&w);
 85         addagefu,v,w);
 86     }
 87     sortee,ee+m,cmp);
 88     forint i=1;i<=n;++i)fa[i]=i;
 89     forint i=0;i<m;++i)
 90     {
 91         int a=findee[i].u),b=findee[i].v);
 92         ifa!=b)
 93         {
 94             fa[a]=b;
 95             addageee[i].u,ee[i].v,ee[i].w);
 96             addageee[i].v,ee[i].u,ee[i].w);
 97             ee[i].nxt=1;
 98             tt+=ee[i].w;
 99             ifjs==2*n-2)break;
100         }
101     }
102     dfs1,0);
103     forint u,v,w,l,i=0;i<m;++i)
104     ifee[i].nxt==0)
105     {
106         u=ee[i].u;v=ee[i].v;w=ee[i].w;
107         l=lcau,v);
108         int a=0,b=0,c=0,d=0,mx,se;
109         worku,l,a,c);
110         workv,l,b,d);
111         mx=maxa,b);
112         ifa==b)se=maxc,d);
113         else ifa>b)se=maxb,c);
114         else se=maxa,d);
115         ifmx!=w) ans=minans,tt+w-mx);
116         else ifw==mx && se!=0)ans=minans,tt+w-se);
117     }
118     cout<<ans;
119     return 0;
120 }

View Code

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注