hdu 4067(最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4067
思路:很神奇的建图,参考大牛的:
如果人为添加t->s的边,那么图中所有顶点要满足的条件都是一样的了,我们以此为目的来建图。
对于每条边,我们只有两种操作,要么保留要么删除,那么先假设两种操作都能满足条件,我们就可以选择花费小的操作来执行,最后再根据实际情况调整。
首先不加入任何边,在添加或删除(不加入)边的过程中,对每个顶点v记录in[v]为其当前入度,out[v]为其出度,sum为当前的总花费。
那么对于每条边,如果a<=b,那么保留这条边,in[v]++,out[u]++,sum+=a,然后连边v->u,流量1,费用为b-a(如果删除这条边的费用)
如果b<a,那么删去这条边,sum+=b,然后连边u->v,流量1,费用为a-b(如果保留这条边的费用)。
然后我们人为的加入一条t->s,直接in[s]++,out[t]++,使得图中所有点处于相同的状况。
设立超级源汇S、T,对于原图的每个点i,如果in[i]>out[i],则连边S->i,流量为in[i]-out[i], 费用为0,否则连边i->T,流量为out[i]-in[i],费用为0。至此,建图完成。
现在求S到T的费用流mincost,然后检查从S发出的边,如果全部满流则有解,答案就是sum+mincost,否则无解。
这样建图的意义:例如对点i,in[i]>out[i],说明当前该点入度大于出度,那么我们把之前删除的以i为起点的边添加回来 或者把之前保留的以i为终点的边删除,现在边的费用其实是改变边状态所需要额外付的费用,而最小费用流所求的就是全部调整的总费用了,于是答案就是sum(初始操作的费用)+mincost(额外付出的费用)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define MAXN 222
#define MAXM 2222222
#define inf 1<<30 struct Edge{
int v,cap,cost,next;
}edge[MAXM]; int n,m,vs,vt,NE;
int head[MAXN]; void Insert(int u,int v,int cap,int cost)
{
edge[NE].v=v;
edge[NE].cap=cap;
edge[NE].cost=cost;
edge[NE].next=head[u];
head[u]=NE++; edge[NE].v=u;
edge[NE].cap=;
edge[NE].cost=-cost;
edge[NE].next=head[v];
head[v]=NE++;
} int dist[MAXN],pre[MAXN],cur[MAXN];
bool mark[MAXN];
bool spfa(int vs,int vt)
{
memset(mark,false,sizeof(mark));
fill(dist,dist+MAXN-,inf);
dist[vs]=;
queue<int>que;
que.push(vs);
while(!que.empty()){
int u=que.front();
que.pop();
mark[u]=false;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v,cost=edge[i].cost;
if(edge[i].cap>&&dist[u]+cost<dist[v]){
dist[v]=cost+dist[u];
pre[v]=u;
cur[v]=i;
if(!mark[v]){
mark[v]=true;
que.push(v);
}
}
}
}
return dist[vt]<inf;
} int MinCostFlow(int vs,int vt)
{
int flow=,cost=;
while(spfa(vs,vt)){
int aug=inf;
for(int u=vt;u!=vs;u=pre[u]){
aug=min(aug,edge[cur[u]].cap);
}
flow+=aug;cost+=dist[vt]*aug;
for(int u=vt;u!=vs;u=pre[u]){
edge[cur[u]].cap-=aug;
edge[cur[u]^].cap+=aug;
}
}
return cost;
} int In[MAXN],Out[MAXN];
bool Judge()
{
for(int i=head[vs];i!=-;i=edge[i].next){
int cap=edge[i].cap;
if(cap>)return false;
}
return true;
} int main()
{
int s,t,u,v,a,b,sum,cost,T=,_case;
scanf("%d",&_case);
while(_case--){
scanf("%d%d%d%d",&n,&m,&s,&t);
NE=;
memset(head,-,sizeof(head));
memset(In,,sizeof(In));
memset(Out,,sizeof(Out));
sum=;
while(m--){
scanf("%d%d%d%d",&u,&v,&a,&b);
if(a<=b){
Insert(v,u,,b-a);
In[v]++,Out[u]++;
sum+=a;
}else {
Insert(u,v,,a-b);
sum+=b;
}
}
In[s]++;
Out[t]++;
vs=,vt=n+;
for(int i=;i<=n;i++){
if(In[i]>Out[i])Insert(vs,i,(In[i]-Out[i]),);
else if(In[i]<Out[i])Insert(i,vt,(Out[i]-In[i]),);
}
cost=MinCostFlow(vs,vt);
printf("Case %d: ",T++);
if(Judge()){
printf("%d\n",sum+cost);
}else
puts("impossible");
}
return ;
}
hdu 4067(最小费用最大流)的更多相关文章
- 【网络流#2】hdu 1533 - 最小费用最大流模板题
最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...
- hdu 1533(最小费用最大流)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- hdu 4862KM&最小费用最大流
/*最小K路径覆盖的模型,用费用流或者KM算法解决, 构造二部图,X部有N*M个节点,源点向X部每个节点连一条边, 流量1,费用0,Y部有N*M个节点,每个节点向汇点连一条边,流量1, 费用0,如果X ...
- HDU 1533 最小费用最大流(模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1533 这道题直接用了模板 题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用 要注意void ...
- hdu 3667(最小费用最大流+拆边)
Transportation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu 6437 /// 最小费用最大流 负花费 SPFA模板
题目大意: 给定n,m,K,W 表示n个小时 m场电影(分为类型A.B) K个人 若某个人连续看了两场相同类型的电影则失去W 电影时间不能重叠 接下来给定m场电影的 s t w op 表示电影的 开始 ...
- hdu 2485(最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2485 思路:题目的意思是删除最少的点使1,n的最短路大于k.将点转化为边,容量为1,费用为0,然后就是 ...
- hdu 6201(最小费用最大流)
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- hdu 2686 Matrix 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...
随机推荐
- SVN 常见命令
一.什么是SVN SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS. 二.SVN的下载安装 下载地址:http ...
- Openerp约束句型
内容摘自:http://blog.csdn.net/sz_bdqn/article/details/8785483 _constraints _constraints可以灵活定义OpenERP对象的约 ...
- 单元测试JUnit 4(二)——keeps the bar green to keeps the code clean
1.Failure和Error Failure是指测试失败 Error是指测试程序本身出错 (int a=10/0) 2.JUnit常用注解 2.1 @RunWith: 可以更改测试运行器(继承o ...
- Servlet容器 Jetty
http://www.oschina.net/p/jettyJetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境.Jetty是使用Java语 ...
- Android第三方推送引擎比较
所了解的第三方推送引擎有极光推送(JPush), 百度, 个推,腾讯信鸽等.根据了解,最专业的据说是极光推送,先看极光推送. 一.极光推送 https://www.jpush.cn/ 配置: 1.JP ...
- navigate是Router类的一个方法,主要用来跳转路由。
navigate是Router类的一个方法,主要用来跳转路由. 1 2 3 4 5 6 7 8 9 interface NavigationExtras { relativeTo : Activat ...
- CENTOS 下安装APK反编译工具 APKTOOL
转于:http://www.qiansw.com/centos-apk-apktool.html 我使用的是CentOS6.4 64位的系统.首先需要下载两个包.这里下载:https://code.g ...
- PHP的CURLOPT_POSTFIELDS参数使用数组和字符串的区别
手册上解释: CURLOPT_POSTFIELDS 全部数据使用HTTP协议中的"POST"操作来发送.要发送文件,在文件名前面加上@前缀并使用完整路径.这个参数可以通过urle ...
- Openresty + nginx-upload-module支持文件上传
0. 说明 这种方式其实复杂,麻烦!建议通过这个方式搭建Openresty文件上传和下载服务器:http://www.cnblogs.com/lujiango/p/9056680.html 1. 包下 ...
- MooseFS管理
一.goal(副本) 副本,在MFS中也被称为目标(Goal),它是指文件被复制的份数,设定目标值后可以通过mfsgetgoal命令来证实,也可以通过mfssetgoal命令来改变设定. 1 2 3 ...