题目大概说,给一张图,删除其中一些单向边,使起点s出度比入度多1,终点t入度比出度多1,其他点出度等于入度。其中删除边的费用是bi,保留边的费用是ai,问完成要求最小的费用是多少。

一开始我想到和混合图欧拉回路(POJ1637)的类似构造方法:

  • 假设所有边一开始都是保留的,算出各个点的入度和出度,另外s点的出度-1,t点的入度-1;
  • 然后把出度-入度等于正数的点源点向其连一条容量为出度-入度的边,等于负数的点其向汇点连一条容量为入度-出度的边
  • 这样就是要通过删除边使那些与源汇相连的边满流,这样就满足各个点度的要求;而删除一条边<u,v>会使u的出度-1,v的入度-1,这样在容量网络中由u向v连容量1费用bi-ai的边
  • Σai-MCMF就是答案

不过这样是错的= =而且因为负环死循环TLE了。我试图想拆点消除负环,发现两端点都与源点或汇点相连的边都不起作用,觉得怪怪的好像不大对,提交果然是WA的。

正确的做法是:一开始不是假设所有边都是保留的,而是贪心地先确定最少的费用,即如果ai<bi则保留否则删除!

然后接下去的做法也是类似的,我就不赘述了。。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 111
#define MAXM 8888
struct Edge{
int u,v,cap,cost,next;
}edge[MAXM];
int vs,vt,NV,NE,head[MAXN];
void addEdge(int u,int v,int cap,int cost){
edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].u=v; edge[NE].v=u; edge[NE].cap=; edge[NE].cost=-cost;
edge[NE].next=head[v]; head[v]=NE++;
}
int d[MAXN],pre[MAXN];
bool vis[MAXN];
bool SPFA(){
for(int i=; i<NV; ++i){
d[i]=INF; vis[i]=;
}
d[vs]=; vis[vs]=;
queue<int> que;
que.push(vs);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap && d[v]>d[u]+edge[i].cost){
d[v]=d[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=;
que.push(v);
}
}
}
vis[u]=;
}
return d[vt]!=INF;
}
int tot;
int MCMF(){
int res=,mxflow=;
while(SPFA()){
int flow=INF,cost=;
for(int u=vt; u!=vs; u=edge[pre[u]].u){
flow=min(flow,edge[pre[u]].cap);
}
mxflow+=flow;
for(int u=vt; u!=vs; u=edge[pre[u]].u){
edge[pre[u]].cap-=flow;
edge[pre[u]^].cap+=flow;
cost+=flow*edge[pre[u]].cost;
}
res+=cost;
}
if(tot!=mxflow) return INF;
return res;
}
int u[],v[],w1[],w2[];
int deg[MAXN];
int main(){
int T,n,m,s,t;
scanf("%d",&T);
for(int cse=; cse<=T; ++cse){
scanf("%d%d%d%d",&n,&m,&s,&t);
int res=;
memset(deg,,sizeof(deg));
--deg[s]; ++deg[t];
for(int i=; i<m; ++i){
scanf("%d%d%d%d",u+i,v+i,w1+i,w2+i);
if(w1[i]<w2[i]){
++deg[u[i]];
--deg[v[i]];
res+=w1[i];
}else{
res+=w2[i];
}
}
tot=;
vs=; vt=n+; NV=vt+; NE=;
memset(head,-,sizeof(head));
for(int i=; i<=n; ++i){
if(deg[i]>) addEdge(vs,i,deg[i],),tot+=deg[i];
else addEdge(i,vt,-deg[i],);
}
for(int i=; i<m; ++i){
if(w1[i]<w2[i]){
addEdge(u[i],v[i],,w2[i]-w1[i]);
}else{
addEdge(v[i],u[i],,w1[i]-w2[i]);
}
}
int tmp=MCMF();
if(tmp==INF) printf("Case %d: impossible\n",cse);
else printf("Case %d: %d\n",cse,res+tmp);
}
return ;
}

HDU4067 Random Maze(最小费用最大流)的更多相关文章

  1. TZOJ 4712 Double Shortest Paths(最小费用最大流)

    描述 Alice and Bob are walking in an ancient maze with a lot of caves and one-way passages connecting ...

  2. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  3. bzoj1927最小费用最大流

    其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→   =_=你TM逗我 刚要删突然感觉dinic的模 ...

  4. ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)

    将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...

  5. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

  6. P3381 【模板】最小费用最大流

    P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...

  7. 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 502[Submit][Status ...

  8. hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***

    题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙,          每个逮捕队伍在每个城市可以选 ...

  9. UVa11082 Matrix Decompressing(最小费用最大流)

    题目大概有一个n*m的矩阵,已知各行所有数的和的前缀和和各列所有数的和的前缀和,且矩阵各个数都在1到20的范围内,求该矩阵的一个可能的情况. POJ2396的弱化版本吧..建图的关键在于: 把行.列看 ...

  10. UVa12092 Paint the Roads(最小费用最大流)

    题目大概说一个n个点m条带权有向边的图,要给边染色,染色的边形成若干个回路且每个点都恰好属于其中k个回路.问最少要染多少边权和的路. 一个回路里面各个点的入度=出度=1,那么可以猜想知道各个点如果都恰 ...

随机推荐

  1. eclipse clear swtich workspace

    edit : --> D:\tools\eclipse\configuration\.settings\org.eclipse.ui.ide.prefs

  2. Web.Config如何输入特殊字符

  3. MVC4方法行为过滤器例子(用户登录)

    在Model文件夹下添加一个类MyActionFilterAttribute继承于ActionFilterAttribute: using System; using System.Collectio ...

  4. Tomcat部署的时候 unpackWARs="true"

    在部署项目到Tomcat的时候发现当Tomcat启动的时候,项目并没有解压出来,导致系统传照片的时候找不到路径,因为,系统没有解压,所以找不到路径, 进入地址==>C:\Users\ceshi\ ...

  5. alias命令(使用命令别名)

    通过alias命令可以给一些命令定义别名,如,将长的难记住的命令起一个容易记住的别名,提高工作效率 alias -p 查看已有的别名列表 命名别名格式: alias 新命令名='原命令名 -参数/选项 ...

  6. 4.1 pair类模板

    在学习关联容器之前,首先先要了解一下STL中的pair类模板,因为关联容器的一些成员函数返回值都是pair对象,而且map 和multimap中的元素都是pair对象. 1)pair类模板定义 pai ...

  7. case/casez/casex 的区分与使用

    参考:http://www.cnblogs.com/poiu-elab/archive/2012/11/02/2751323.html 与  verilog数字系统设计基础 一般来说,使用最多的是CA ...

  8. 字符识别(模板匹配&BP神经网络训练)

    http://blog.csdn.net/zhang11wu4/article/details/7585632

  9. SQLServer之数据类型

    1.整数数据类型整数数据类型是常用的数据类型之一,主要用于存储数值,可以直接进行数据运算而不必使用函数转换.(1).bigint 每个bigint存储在8个字节中,其中一个二进制位表示符号位,其它63 ...

  10. C#的反射机制

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...