题目大概说,给一张图,删除其中一些单向边,使起点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. ios tableview 适配横竖屏

    tableview.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

  2. September 23rd 2016 Week 39th Friday

    Even a small star shines in the darkness. 星星再小,也会发光. In the darkness, even a small star can shine. N ...

  3. July 9th, Week 28th Saturday, 2016

    Every cloud has a silver lining. 山穷水尽疑无路,柳暗花明又一村. Every cloud has a silver lining, that just because ...

  4. 升级CUDA版本导致VS2010错误:未找到导入的项目XXX,请确认<Import>声明中的路径正确,且磁盘上存在该文件

    转自:http://www.cnblogs.com/yeahgis/p/3853420.html VS2010错误:未找到导入的项目XXX,请确认<Import>声明中的路径正确,且磁盘上 ...

  5. eclipse svn设置忽略文件

  6. 实现iOS前台时的推送弹窗效果

    原文链接 或许很多童鞋还不知道,在 iOS 中收到推送通知时,如果 App 处于前台运行的情况下,推送的顶部弹窗是不会弹出来的. 然而就是有很多**的产品经理都会提出类似这样的**需求:那就是在 Ap ...

  7. CSS3混合模式background-blend-mode

    注意:background属性中的背景图片和颜色混合,只能在一个background属性中. 属性值: background-blend-mode: normal; //正常 background-b ...

  8. Java使用正则表达式解析LRC歌词文件

    LRC歌词是一种应用广泛的歌词文件,各主流播放器都支持. lrc歌词文本中含有两类标签: 1.标识标签(ID-tags) [ar:艺人名] [ti:曲名] [al:专辑名] [by:编者(指编辑LRC ...

  9. MVC – 8.Razor 布局

    8.1.@RenderBody() 8.2.多个"占位符":@RenderSection() 8.3.js合并 @Scripts.Render("~/bundles/js ...

  10. Linux安装mysql最新版本纪要

    http://blog.csdn.net/frt007/article/details/50184143 http://blog.csdn.net/wb96a1007/article/details/ ...