题目大概说,给一张图,删除其中一些单向边,使起点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则保留否则删除!

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

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<algorithm>
  5. using namespace std;
  6. #define INF (1<<30)
  7. #define MAXN 111
  8. #define MAXM 8888
  9. struct Edge{
  10. int u,v,cap,cost,next;
  11. }edge[MAXM];
  12. int vs,vt,NV,NE,head[MAXN];
  13. void addEdge(int u,int v,int cap,int cost){
  14. edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
  15. edge[NE].next=head[u]; head[u]=NE++;
  16. edge[NE].u=v; edge[NE].v=u; edge[NE].cap=; edge[NE].cost=-cost;
  17. edge[NE].next=head[v]; head[v]=NE++;
  18. }
  19. int d[MAXN],pre[MAXN];
  20. bool vis[MAXN];
  21. bool SPFA(){
  22. for(int i=; i<NV; ++i){
  23. d[i]=INF; vis[i]=;
  24. }
  25. d[vs]=; vis[vs]=;
  26. queue<int> que;
  27. que.push(vs);
  28. while(!que.empty()){
  29. int u=que.front(); que.pop();
  30. for(int i=head[u]; i!=-; i=edge[i].next){
  31. int v=edge[i].v;
  32. if(edge[i].cap && d[v]>d[u]+edge[i].cost){
  33. d[v]=d[u]+edge[i].cost;
  34. pre[v]=i;
  35. if(!vis[v]){
  36. vis[v]=;
  37. que.push(v);
  38. }
  39. }
  40. }
  41. vis[u]=;
  42. }
  43. return d[vt]!=INF;
  44. }
  45. int tot;
  46. int MCMF(){
  47. int res=,mxflow=;
  48. while(SPFA()){
  49. int flow=INF,cost=;
  50. for(int u=vt; u!=vs; u=edge[pre[u]].u){
  51. flow=min(flow,edge[pre[u]].cap);
  52. }
  53. mxflow+=flow;
  54. for(int u=vt; u!=vs; u=edge[pre[u]].u){
  55. edge[pre[u]].cap-=flow;
  56. edge[pre[u]^].cap+=flow;
  57. cost+=flow*edge[pre[u]].cost;
  58. }
  59. res+=cost;
  60. }
  61. if(tot!=mxflow) return INF;
  62. return res;
  63. }
  64. int u[],v[],w1[],w2[];
  65. int deg[MAXN];
  66. int main(){
  67. int T,n,m,s,t;
  68. scanf("%d",&T);
  69. for(int cse=; cse<=T; ++cse){
  70. scanf("%d%d%d%d",&n,&m,&s,&t);
  71. int res=;
  72. memset(deg,,sizeof(deg));
  73. --deg[s]; ++deg[t];
  74. for(int i=; i<m; ++i){
  75. scanf("%d%d%d%d",u+i,v+i,w1+i,w2+i);
  76. if(w1[i]<w2[i]){
  77. ++deg[u[i]];
  78. --deg[v[i]];
  79. res+=w1[i];
  80. }else{
  81. res+=w2[i];
  82. }
  83. }
  84. tot=;
  85. vs=; vt=n+; NV=vt+; NE=;
  86. memset(head,-,sizeof(head));
  87. for(int i=; i<=n; ++i){
  88. if(deg[i]>) addEdge(vs,i,deg[i],),tot+=deg[i];
  89. else addEdge(i,vt,-deg[i],);
  90. }
  91. for(int i=; i<m; ++i){
  92. if(w1[i]<w2[i]){
  93. addEdge(u[i],v[i],,w2[i]-w1[i]);
  94. }else{
  95. addEdge(v[i],u[i],,w1[i]-w2[i]);
  96. }
  97. }
  98. int tmp=MCMF();
  99. if(tmp==INF) printf("Case %d: impossible\n",cse);
  100. else printf("Case %d: %d\n",cse,res+tmp);
  101. }
  102. return ;
  103. }

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. 树形DP习题

    听闻noip要考树形DP,本蒟蒻万分惶恐,特刷一坨题目,以慰受惊之心. codevs 1486 /*和非常出名的"选课"是一个题*/ #include<cstdio> ...

  2. Mysql之多源复制

    在复制时,可以有多个Master.这些Master不进行冲突检查拓扑到Slave.在使用多源复制时对Slave的表存储格式是有要求的,必须要基于table存储而非文件存储[require table ...

  3. elipse插件整理

    整理一下用过的eclipse插件: 1. WindowBuilder :swing插件,可以拖啊拖啊拖出来一个窗口,可以显著提高开发效率.   官网: http://www.eclipse.org/w ...

  4. 借助LinkedHashMap实现基于LRU算法缓存

    一.LRU算法介绍 LRU(Least Recently Used)最近最少使用算法,是用在操作系统中的页面置换算法,因为内存空间是有限的,不可能把所有东西都放进来,所以就必须要有所取舍,我们应该把什 ...

  5. iOS源码之OC相册,可以循环查看图片

    #import "ViewController.h" #import "YZUIScrollView.h" #define kuan ([UIScreen ma ...

  6. IOS常用正则表达式

    IOS常用正则表达式 正则表达式用于字符串处理.表单验证等场合,实用高效.现将一些常用的表达式收集于此,以备不时之需. 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 评注:匹配中文还真是 ...

  7. ASP.NET MVC中ViewData、ViewBag和TempData

    1.ViewData 1.1 ViewData继承了IDictionary<string, object>,因此在设置ViewData属性时,传入key必须要字符串型别,value可以是任 ...

  8. ASP.NET MVC中Controller返回值类型ActionResult

    1.返回ViewResult视图结果,将视图呈现给网页 public class TestController : Controller { //必须存在Controller\Test\Index.c ...

  9. Python 自然语言处理(1) 计数词汇

    Python有一个自然语言处理的工具包,叫做NLTK(Natural Language ToolKit),可以帮助你实现自然语言挖掘,语言建模等等工作.但是没有NLTK,也一样可以实现简单的词类统计. ...

  10. async/await 异步编程(转载)

    转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...