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人环 ...
随机推荐
- 201871030136-颜静 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST/ 这个作业要求链接 https://www.cnblogs.com/nwnu- ...
- 如何选择视觉CV光源颜色
如何选择视觉CV光源颜色 一.光源颜色分类 光源颜色的选择对机器视觉光源有什么影响及意义呢,常用的光源颜色有白色(W).蓝色(B).红色(R).绿色(G).红外光(IR).紫外光(UV),这六种颜色. ...
- 国内操作系统OS分析(上)
国内操作系统OS分析(上) 一.操作系统(OS)概述 操作系统(OS,Operating System),是管理.控制计算机软硬件资源的计算机程序,并为用户提供一个与系统交互的操作界面.OS是配置在计 ...
- RADAR和LIDAR区别分析
RADAR和LIDAR区别分析 如果一直关注自动驾驶汽车的新闻,可能已经注意到许多自动驾驶汽车制造商正在使用LIDAR(光成像检测和测距)进行车载物体检测.对于许多自动 驾驶汽车应用而言,LIDAR比 ...
- CSS 常见问题笔记
CSS 常见问题 布局 一.盒模型宽度计算 问题:div1 的 offsetWidth 是多少? <style> #div1 { width: 100px; padding: 10px; ...
- 【NX二次开发】Block UI 枚举
属性: 常规 类型 描述 BlockID String 控件ID Enable Logical 是否可操作 Group Logical ...
- 【VBA】获取文件夹下所有文本文件
源码: 1 Sub 获取文件夹下所有文本文件() 2 Dim strPath As String 3 strPath = "G:\A\" 4 Dim MyFile As Strin ...
- Mysql慢SQL分析及优化
为何对慢SQL进行治理 从数据库角度看:每个SQL执行都需要消耗一定I/O资源,SQL执行的快慢,决定资源被占用时间的长短.假设总资源是100,有一条慢SQL占用了30的资源共计1分钟.那么在这1分钟 ...
- 飞(fly)(数学推导,liu_runda的神题)
大概看了两三个小时的题解,思考量很大,实现简单........ 20分: 明显看出,每个点的贡献是x*(x-1)/2;即组合数C(x,2),从x个线段中选出2个的方案数,显然每次相交贡献为1,n^2枚 ...
- 一文读懂高速PCB设计跟高频放大电路应用当中的阻抗匹配原理
这一期课程当中,我们会重点介绍高频信号传输当中的阻抗匹配原理以及共基极放大电路在高频应用当中需要注意的问题,你将会初步了解频率与波长的基础知识.信号反射的基本原理.特性阻抗的基本概念以及怎么样为放大电 ...