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

数据范围与提示

对于全部数据,1≤N≤500,1≤M≤10^4,1≤z≤10^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 addage(int 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 addagef(int u,int v,int w)
18 {
19 ee[jss].u=u;ee[jss].v=v;ee[jss++].w=w;
20 }
21 bool cmp(edge a,edge b)
22 {
23 return a.w<b.w;
24 }
25 int fa[maxn];
26 int find(int x)
27 {
28 return fa[x]==x?x:fa[x]=find(fa[x]);
29 }
30 int f[maxn][10],ff[maxn][10],fs[maxn][10],dep[maxn];
31 void dfs(int u,int fat)
32 {
33 dep[u]=dep[fat]+1;
34 for(int i=head[u];i;i=e[i].nxt)
35 {
36 int v=e[i].v;
37 if(v!=fat)
38 {
39 f[v][0]=u;
40 ff[v][0]=e[i].w;
41 for(int 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]=max(a,b);
46 if(a==b)fs[v][i]=max(c,d);
47 else if(a>b)fs[v][i]=max(b,c);
48 else fs[v][i]=max(a,d);
49 }
50 dfs(v,u);
51 }
52 }
53 }
54 int lg[maxn];
55 int lca(int u,int v)
56 {
57 lg[0]=-1;
58 for(int i=1;i<=n;++i)lg[i]=lg[i>>1]+1;
59 if(dep[u]<dep[v])swap(u,v);
60 while(dep[u]>dep[v])u=f[u][lg[dep[u]-dep[v]]];
61 if(u==v)return u;
62 for(int i=lg[dep[u]];i>=0;--i)
63 if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
64 return f[u][0];
65 }
66 void work(int u,int l,int &mx,int &se)
67 {
68 while(dep[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=max(a,b);
74 if(a==b)se=max(c,d);
75 else if(a>b)se=max(b,c);
76 else se=max(a,d);
77 }
78 }
79 int main()
80 {
81 scanf("%d%d",&n,&m);
82 for(int u,v,w,i=0;i<m;++i)
83 {
84 scanf("%d%d%d",&u,&v,&w);
85 addagef(u,v,w);
86 }
87 sort(ee,ee+m,cmp);
88 for(int i=1;i<=n;++i)fa[i]=i;
89 for(int i=0;i<m;++i)
90 {
91 int a=find(ee[i].u),b=find(ee[i].v);
92 if(a!=b)
93 {
94 fa[a]=b;
95 addage(ee[i].u,ee[i].v,ee[i].w);
96 addage(ee[i].v,ee[i].u,ee[i].w);
97 ee[i].nxt=1;
98 tt+=ee[i].w;
99 if(js==2*n-2)break;
100 }
101 }
102 dfs(1,0);
103 for(int u,v,w,l,i=0;i<m;++i)
104 if(ee[i].nxt==0)
105 {
106 u=ee[i].u;v=ee[i].v;w=ee[i].w;
107 l=lca(u,v);
108 int a=0,b=0,c=0,d=0,mx,se;
109 work(u,l,a,c);
110 work(v,l,b,d);
111 mx=max(a,b);
112 if(a==b)se=max(c,d);
113 else if(a>b)se=max(b,c);
114 else se=max(a,d);
115 if(mx!=w) ans=min(ans,tt+w-mx);
116 else if(w==mx && se!=0)ans=min(ans,tt+w-se);
117 }
118 cout<<ans;
119 return 0;
120 }

LOJ10068 秘密的牛奶运输的更多相关文章

  1. 「LOJ#10068」「一本通 3.1 练习 3」秘密的牛奶运输(次小生成树

    题目描述 Farmer John 要把他的牛奶运输到各个销售点.运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点. 运输的总距离越小,运输的成本也就越低.低成本的运输是 F ...

  2. 2018.09.15 秘密的牛奶管道SECRET(次小生成树)

    描述 约翰叔叔希望能够廉价连接他的供水系统,但是他不希望他的竞争对手知道他选择的路线.一般这样的问题需要选择最便宜的方式,所以他决定避免这种情况而采用第二便宜的方式. 现在有W(3 <= W & ...

  3. loj题目总览

    --DavidJing提供技术支持 现将今年7月份之前必须刷完的题目列举 完成度[23/34] [178/250] 第 1 章 贪心算法 √ [11/11] #10000 「一本通 1.1 例 1」活 ...

  4. CSU训练分类

    √√第一部分 基础算法(#10023 除外) 第 1 章 贪心算法 √√#10000 「一本通 1.1 例 1」活动安排 √√#10001 「一本通 1.1 例 2」种树 √√#10002 「一本通 ...

  5. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  6. CPU阿甘:函数调用的秘密

    个人感言:真正的知识是深入浅出的,码农翻身" 公共号将苦涩难懂的计算机知识,用形象有趣的生活中实例呈现给我们,让我们更好地理解.感谢"码农翻身" 公共号,感谢你们的成果, ...

  7. TypeScript: Angular 2 的秘密武器(译)

    本文整理自Dan Wahlin在ng-conf上的talk.原视频地址: https://www.youtube.com/watch?v=e3djIqAGqZo 开场白 开场白主要分为三部分: 感谢了 ...

  8. [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密

    string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...

  9. 网站的SEO以及它和站长工具的之间秘密

    博客迁移没有注意 URL 地址的变化,导致百度和 google 这两只爬虫引擎短时间内找不到路.近段时间研究了下国内最大搜索引擎百度和国际最大搜索引擎google的站长工具,说下感受. 百度的站长工具 ...

随机推荐

  1. Android驱动学习-app调用内核驱动过程(驱动框架回顾)

    考研已经过去了,android驱动的学习也断了半年多了,现在重新捡起来学习,回顾一下Android驱动的大体框架. Android系统的核心是java,其有一个David虚拟机.Android-app ...

  2. Arduino IDE开发ESP8266-01S连接MQTT服务器 控制继电器点亮LED

    准备条件: 1.Arduino IDE 2.ESP-01S模块 2.MQTT服务器 3.手机热点或路由器热点 Wi-Fi芯片 默认订阅的主题是  "开关控制" 当你发送主题  &q ...

  3. Hadoop支持的压缩格式对比和应用场景以及Hadoop native库

    对于文件的存储.传输.磁盘IO读取等操作在使用Hadoop生态圈的存储系统时是非常常见的,而文件的大小等直接影响了这些操作的速度以及对磁盘空间的消耗. 此时,一种常用的方式就是对文件进行压缩.但文件被 ...

  4. MongoDb学习(五)--Gridfs--上传下载

    版本 <dependency> <groupId>org.springframework.data</groupId> <artifactId>spri ...

  5. Lightweight Render Pipeline

    (翻译) Lightweight Render Pipeline (LWRP),轻量级渲染管线,是一个Unity预制的Scriptable Render Pipeline (SRP).LWRP可以为移 ...

  6. CountDownLatch/CyclicBarrier/Semaphore 使用过吗

    CountDownLatch 让一些线程堵塞直到另一个线程完成一系列操作后才被唤醒.CountDownLatch 主要有两个方法,当一个或多个线程调用 await 方法时,调用线程会被堵塞,其他线程调 ...

  7. 一个简单的字符串,为什么 Redis 要设计的如此特别

    Redis 的 9 种数据类型 本文GitHub已收录:https://zhouwenxing.github.io/ Redis 中支持的数据类型到 5.0.5 版本,一共有 9 种.分别是: 1.B ...

  8. Sql Server Sum函数的特殊使用

    利用Sql Server的Sum函数开窗得到累计值 具体详解https://www.cnblogs.com/zhaoshujie/p/9594676.html 个人示例例子 DECLARE @Sale ...

  9. 【MyBatis】MyBatis 动态 SQL

    MyBatis 动态SQL if 可以根据实体类的不同取值,使用不同的 SQL 语句来进行查询. 使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分. 持久层 DAO 接口: pub ...

  10. MySQL 使用MD5对数据进行加密

    数据库MD5加密 -- ================ 测试 MD5 加密 ============== CREATE TABLE `testmd5`( id INT(11) NOT NULL AU ...