Luogu P4553 80人环游世界
题目大意
自东向西有 \(n\) 个国家。有 \(m\) 个人,他们可以选择 \(n\) 个国家中任意一个开始,任意一个结束,但路线必须自东向西,且第 \(i\) 个国家必须恰好经过 \(v_i\) 人。已知每个国家到它西方的国家的费用,求最小花费。
最小费用最大流
蒟蒻不会上下界,看了一些大佬写的费用流,想了一下,发表一下自己的理解,希望对大家有帮助。
首先因为对于每个点(国家)都有经过限制,所以将拆点为入点和出点。 \(i\rightarrow (i,i+n)\)
\(s\) 向第 \(i\) 入点连容量 \(v_i\) 费用 \(0\) 的边,因为每个国家必须要有 \(v_i\) 人来,连这条边就相当于这 \(v_i\) 个人进入了该国。
同理,出点向 \(t\) 连容量 \(v_i\)费用 \(0\) 的边,表示有 \(v_i\) 个人到达了这个国家。
对于每条航线 \((u,v)\),由 \(u\) 的入点向 \(v\) 的出点连容量 \(\infty\) 费用 \(0\) 的边,表示进入国家 \(u\) 的人可以前往国家 \(v\) 并声明到达了国家 \(v\) (即从 \(v\) 的出点到达汇点)。
最后额外再建一个点,由 \(s\) 向它连容量 \(m\) 费用 \(0\) 的边,然后让他向每个出点连容量 \(\infty\) 费用 \(0\) 的边表示这 \(m\) 个人可以随便选出发点。
然后跑最小费用最大流即可。
考虑正确性:因为跑的是最大流,所以每个出点到汇点的边一定会跑满,也就保证了每个国家限定经过次数。
又因为从那个额外点到其他出点的边费用为 \(0\) 所以这些边会被优先选择,也就意味着从源点到额外点着条边一定会跑满,也就意味着这 \(m\) 个人一定会出发(不会有人临阵脱逃)。
Code
#include<bits/stdc++.h>
//#define int long long
#define pair pair<int,int>
using namespace std;
inline void end()
{
puts("");
system("pause");
}
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
const int N=222,M=2e4+4,inf=0x3f3f3f3f,INF=1e9;
int s,t,maxf,minc;
int first[N],nex[M],to[M],w[M],c[M],num=1;
inline void add(int u,int v,int val,int cos)
{
nex[++num]=first[u];
first[u]=num;
to[num]=v;
w[num]=val;
c[num]=cos;
}
inline void Add(int u,int v,int val,int cos)
{
add(u,v,val,cos);
add(v,u,0,-cos);
}
int dis[N],vis[N],cur[N];
inline bool SPFA()
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
deque<int> q;
q.push_back(s);
vis[s]=1;dis[s]=0;
while(!q.empty())
{
int u=q.front();q.pop_front();vis[u]=0;
for(int i=first[u];i;i=nex[i])
{
int v=to[i];
if(!w[i]) continue;
if(dis[v]>dis[u]+c[i])
{
dis[v]=dis[u]+c[i];
if(!vis[v])
{
vis[v]=1;
if(q.empty()||dis[v]>dis[q.front()]) q.push_back(v);
else q.push_front(v);
}
}
}
}
if(dis[t]==inf) return 0;
return 1;
}
int dfs(int u,int in)
{
if(u==t) return in;
vis[u]=1;
int out=0;
for(int i=cur[u];i;i=nex[i])
{
int v=to[i];
if(!w[i]||vis[v]) continue;
if(dis[v]==dis[u]+c[i])
{
int res=dfs(v,min(w[i],in-out));
w[i]-=res;
w[i^1]+=res;
out+=res;
minc+=c[i]*res;
if(in==out) break;
}
}
vis[u]=0;
if(!out) vis[u]=1;
return out;
}
void Dinic()
{
while(SPFA())
{
memcpy(cur,first,sizeof(first));
while(1)
{
int detal=dfs(s,1e9);
if(!detal) break;
maxf+=detal;
}
}
}
int n,m,v[N],ex;
main()
{
n=read(),m=read();ex=2*n+1;s=0,t=ex+1;
//ex为额外点
Add(s,ex,m,0);
for(int i=1;i<=n;++i)
{
v[i]=read();
Add(i+n,t,v[i],0);
Add(ex,i+n,INF,0);
}
for(int i=1;i<=n;++i)
{
Add(s,i,v[i],0);
for(int j=i+1;j<=n;++j)
{
int val=read();
if(val==-1) continue;
Add(i,j+n,INF,val);
}
}
Dinic();//最小费用最大流
printf("%d",minc);
//end();
return 0;
}
Luogu P4553 80人环游世界的更多相关文章
- P4553 80人环游世界
题目地址:P4553 80人环游世界 上下界网络流 无源汇上下界可行流 给定 \(n\) 个点, \(m\) 条边的网络,求一个可行解,使得边 \((u,v)\) 的流量介于 \([B(u,v),C( ...
- P4553 80人环游世界(上下界费用流)
P4553 80人环游世界 emm......先从上下界网络流(转)开始 再到现在的上下界费用流 因为有上下界,我们需要记下每个点的流量差$ex[i]$,用于调整 $ins(x,y,l,r,v)=li ...
- 洛谷P4553 80人环游世界
题目描述 https://www.luogu.org/problemnew/show/P4553 题解 思路比较显然,把图建出来,一个国家拆成两个点,中间设置上下界,然后跑费用流. 我把源那边的流量也 ...
- 【BZOJ-2055】80人环游世界 上下界费用流 (无源无汇最小费用最大流)
2055: 80人环游世界 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 321 Solved: 201[Submit][Status][Discus ...
- BZOJ2055: 80人环游世界
题解: 总算A掉了,各种蛋疼... int main() { freopen("input.txt","r",stdin); freopen("out ...
- BZOJ 2055: 80人环游世界 [上下界费用流]
2055: 80人环游世界 题意:n个点带权图,选出m条路径,每个点经过val[i]次,求最小花费 建图比较简单 s拆点限制流量m 一个点拆成两个,限制流量val[i],需要用上下界 图中有边的连边, ...
- [BZOJ2055]80人环游世界 有上下界最小费用最大流
2055: 80人环游世界 Time Limit: 10 Sec Memory Limit: 64 MB Description 想必大家都看过成龙大哥的<80天环游世界>,里面 ...
- bzoj 2055: 80人环游世界 -- 上下界网络流
2055: 80人环游世界 Time Limit: 10 Sec Memory Limit: 64 MB Description 想必大家都看过成龙大哥的<80天环游世界>,里面 ...
- 【BZOJ】2055 80人环游世界
[算法]有源汇上下界最小费用可行流 [题解]上下界 因为上下界相同,所以无所谓最小流了,可行流(初始流+附加流)就是答案了. 记得源点向新建节点连一条容量为m(人)的边. bzoj 2055 80人环 ...
随机推荐
- VMware vSphere 7.0 Update 2 发布 - 数据中心虚拟化和 Kubernetes 云原生应用引擎
2021 年 3 月 9 日,VMware 发布了 vSphere 7 Update 2.它可以通过 VMware Customer Connect 和 vSphere Lifecycle Manag ...
- java中的NIO和IO到底是什么区别?20个问题告诉你答案
摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...
- Mobileye 自动驾驶策略(一)
Mobileye 自动驾驶策略(一) 详解 Mobileye 自动驾驶解决方案 Mobileye的自动驾驶解决方案.总得来说,分为四种: Visual perception and sensor fu ...
- YOLOv4实用训练实践
YOLOv4实用训练实践 准备工作 推荐使用Ubuntu 18.04 CMake >= 3.8: https://cmake.org/download/ CUDA >= 10.0: htt ...
- ISP算法高水平分析(下)
ISP算法高水平分析(下) 十.LSC(Lens Shade Correction)------镜头阴影矫正 Lens Shading指画面四角由于入射光线不足形成的暗角,同时,由于不同频率的光折射 ...
- MindSpore网络模型类
MindSpore网络模型类 Q:使用MindSpore进行模型训练时,CTCLoss的输入参数有四个:inputs, labels_indices, labels_values, sequence_ ...
- SOC,System on-a-Chip技术初步
SOC,System on-a-Chip技术初步 S O C(拼作S-O-C)是一种集成电路,它包含了电子系统在单个芯片上所需的所有电路和组件.它可以与传统的计算机系统形成对比,后者由许多不同的组件组 ...
- CVPR2020:利用图像投票增强点云中的三维目标检测(ImVoteNet)
CVPR2020:利用图像投票增强点云中的三维目标检测(ImVoteNet) ImVoteNet: Boosting 3D Object Detection in Point Clouds With ...
- 分布式 redis 延时任务 基于 springboot 示例
Lilishop 技术栈 官方公众号 & 开源不易,如有帮助请点Star 介绍 官网:https://pickmall.cn Lilishop 是一款Java开发,基于SpringBoot研发 ...
- 03:CSS(01)
内容概要 分组与嵌套 伪类选择器 伪元素选择器 选择器优先级 css属性相关(操作标签样式) 浮动 定位 模态框 透明度 内容详细 分组与嵌套 div,p,span { /*逗号表示并列关系*/ co ...