题目:

洛谷2469

分析:

把题目翻译成人话:给一个带边权的DAG,求一个路径覆盖方案使路径边权总和最小。从点\(i\)开始的路径需要额外加上\(A_i\)的权值。

回xian忆chang一xue下xi不带权DAG的最小路径覆盖用网络流是怎么做的:把点\(u\)拆成\(u\)和\(u'\)两个点,如果原图存在边\((u,v)\)就在网络中连边\((u,v')\),然后源点\(s\)向所有\(u\)连边,所有\(v\)向汇点\(t\)连边,所有边容量均为\(1\),跑最大流。原图中点数\(n\)减去最大流就是最小路径覆盖。

考虑这样做的原理:最小路径覆盖中每个点属于且仅属于一条路径。对于任意包含多于\(1\)个点的路径,有且只有一个点入度为\(0\),一个点出度为\(0\),其余所有点入度、出度皆为\(1\)。网络中若\((s,u)\)有流量说明\(u\)出度为\(1\)(\(s\)流到\(u\)后必然要流向某个点\(v'\)),若\((u',t)\)有流量说明\(u\)入度为\(1\)(必须有某个点流到\(u'\),\((u',t)\)才有流量)。那么最大流就是所有点入度之和,\(n\)减去入度之和就是入度为\(0\)的点数,即路径起点的数量,即路径数。如果边\((u,v')\)有流量说明原图中\((u,v)\)这条边在最小路径覆盖中。

那么给每条边加上权以后呢?自然能想到把原图中边\((u,v)\)的权作为网络中\((u,v')\)的费用然后跑费用流

然后你就gg了

费用流全名叫“最小费用最大流”,是在保证流量最大的情况下的最小费用。在这道题中,就相当于首先要保证路径的条数最少(即流量最大),然后再使费用最小。此时要感谢某神犇T兔z崽z子给我说的我自己想出来的方法……先打个广告

戳我进入兔崽子的博客

\(s\)向每个\(u'\)连边,这条边有流量说明\(u\)入度为\(0\)(因为\((u',t)\)容量为\(1\),\((s,u‘)\)有流量就说明肯定没有别的点会流到\(u'\))。这样无论如何路径覆盖最大流都是\(n\),就消除了路径条数的影响,求出最小费用即为答案。

这种方案顺便解决了下一个问题:路径起点有额外权值。把\(A_u\)作为\((s,u')\)的费用即可。

代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
namespace zyt
{
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int N = 810, P = N * 2, M = (N * 3 + 15010) * 2;
int head[P], cnt, n, m, s, t;
struct edge
{
int to, w, c, next;
}e[M];
inline void add(const int a, const int b, const int c, const int d)
{
e[cnt] = (edge){b, c, d, head[a]};
head[a] = cnt++;
}
inline void addtw(const int a, const int b, const int c, const int d)
{
add(a, b, c, d);
add(b, a, 0, -d);
}
namespace EK
{
bool vis[P];
ll dis[P];
int pre[P];
bool SPFA()
{
queue<int>q;
memset(pre, -1, sizeof(pre));
memset(vis, 0, sizeof(vis));
memset(dis, INF, sizeof(dis));
q.push(s);
vis[s] = true;
dis[s] = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for (int i = head[u]; ~i; i = e[i].next)
{
int v = e[i].to;
if (e[i].w && dis[v] > dis[u] + e[i].c)
{
dis[v] = dis[u] + e[i].c, pre[v] = i;
if (!vis[v])
vis[v] = true, q.push(v);
}
}
}
return dis[t] != INF;
}
ll EK()
{
ll ans = 0;
while (SPFA())
{
int i = pre[t];
int minn = n + 1;
while (~i)
minn = min(minn, e[i].w), i = pre[e[i ^ 1].to];
i = pre[t];
while (~i)
e[i].w -= minn, e[i ^ 1].w += minn, i = pre[e[i ^ 1].to];
ans += minn * dis[t];
}
return ans;
}
}
int work()
{
ios::sync_with_stdio(false);
memset(head, -1, sizeof(head));
cin >> n >> m;
s = n * 2 + 1, t = n * 2 + 2;
for (int i = 1; i <= n; i++)
{
int a;
cin >> a;
addtw(s, i, 1, 0);
addtw(s, i + n, 1, a);
addtw(i + n, t, 1, 0);
}
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
if (a > b)
swap(a, b);
addtw(a, b + n, 1, c);
}
cout << EK::EK();
return 0;
}
}
int main()
{
return zyt::work();
}

【洛谷2469/BZOJ1927】[SDOI2010]星际竞速(费用流/最小路径覆盖)的更多相关文章

  1. BZOJ 1927: [Sdoi2010]星际竞速 费用流

    1927: [Sdoi2010]星际竞速 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. Luogu2469 SDOI2010 星际竞速 费用流

    传送门 发现它的本质是求一个费用最小的路径覆盖 最小路径覆盖是网络流23题中的一个比较典型的模型 所以考虑相似的建边 因为每一个点要恰好经过一次,是一个有上下界的网络流,故拆点,星球\(i\)拆成\( ...

  3. BZOJ 1927: [Sdoi2010]星际竞速(费用流)

    传送门 解题思路 仿照最小路径覆盖问题,用费用流解决此题.最小路径覆盖问题是拆点连边后用\(n-\)最大匹配,这里的话也是将每个点拆点,源点向入点连流量为\(1\),费用为\(0\)的边,向出点连流量 ...

  4. [SDOI2010]星际竞速——费用流

    类似于最短路的网络流,而且还要保证每个点经过一次,拆点就比较方便了. 连边怎么连?要保证最大流是n(每个点经过一次)还要能从直接跳转 将每个点拆点.源点向每个点的入点连一条容量为1费用为0的边.源点向 ...

  5. BZOJ1927 [Sdoi2010]星际竞速 【费用流】

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec  Memory Limit: 259 MB Submit: 2582  Solved: 1601 [Submit][St ...

  6. BZOJ1927: [Sdoi2010]星际竞速(最小费用最大流 最小路径覆盖)

    题意 题目链接 Sol 看完题不难想到最小路径覆盖,但是带权的咋做啊?qwqqq 首先冷静思考一下:最小路径覆盖 = \(n - \text{二分图最大匹配数}\) 为什么呢?首先最坏情况下是用\(n ...

  7. bzoj1927: [Sdoi2010]星际竞速

    跟上一题几乎一样... #include<cstdio> #include<cstring> #include<iostream> #include<algo ...

  8. BZOJ 1927 星际竞速(费用流)

    考虑费用流,题目要求走n个点都走完且恰好一次,显然流量的限制为n. 建立源点s和汇点t,并把每个星球拆成两个点i和i',分别表示已到达该点和经过该点. 对于能力爆发,建边(s,i',1,w). 对应高 ...

  9. 洛谷 P4016负载平衡问题【费用流】题解+AC代码

    洛谷 P4016负载平衡问题 P4014 分配问题[费用流]题解+AC代码 负载平衡问题 题目描述 GG 公司有n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n ...

随机推荐

  1. jdk版本特性

    https://segmentfault.com/a/1190000004419611 java5 泛型 枚举 装箱拆箱 变长参数 注解 foreach循环 静态导入 格式化 线程框架/数据结构 Ar ...

  2. 洛谷 2146 [NOI2015]软件包管理器

    [题解] 每个软件只依赖另一个软件,且依赖关系不构成环,那么很容易想到这是树形结构. 我们用1表示以安装,用0表示未安装或已卸载:那么安装一个软件,就是把它到树根的路径上所有的点都改为1:卸载一个软件 ...

  3. How Can You Tell the Difference Between LINQ Methods and Query Builder Methods?

    LINQ's method syntax looks very similar to the query builder methods,except for one big difference:t ...

  4. JavaSE 学习笔记之Jdk5.0新特性(十九)

    Jdk5.0新特性: Collection在jdk1.5以后,有了一个父接口Iterable,这个接口的出现的将iterator方法进行抽取,提高了扩展性. --------------------- ...

  5. MaxScale初探

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://mrcto.blog.51cto.com/1923168/1437287 内容预览 ...

  6. 20180710使用gh

    转自:http://www.ywnds.com/?p=14265 一.背景 GitHub正式宣布以开源的方式发布gh-ost:GitHub的MySQL无触发器在线更改表定义工具!下面是官方给出gh-o ...

  7. T1082 线段树练习3 codevs

    http://codevs.cn/problem/1082/ 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 ...

  8. vijos——1164 曹冲养猪

    描述 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把.举个例子,假如有16 ...

  9. 串口调试助手---VB源码

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  10. Ubuntu安装Sublime Text并输入中文

    Sumblime Text3是一款传说中的神级代码编辑器,具有下面特点: 1.代码高亮,自己主动补全 2.各种插件扩展 3.外观简洁舒适 4.跨平台(Windows,Linux,OS X) 简而言之就 ...