题意: 在一般费用流题目改动:路过某路,每x单位流量须要花费 ai*x^2(ai为给定的系数)。

開始的的时候,一看仅仅只是是最后统计费用上在改动罢了,一看例子。发现根本没那么简单(ps:以后每次写程序前先看例子能不能过。),由于是成平方关系。每次一流量增广的话。下次未必最优!于是想到我每次仅仅增长一个单位流量。每次增长一个单位之后,该路径上的全部边的费用边改为i^2-(i-1)^2,(第一次肯定增广a,其次的话3a.5a.7a.。。。由于第一次已经增广了,和为第i次i平方就可以!

)如此。符合题意!

一提交Wa!扫了一遍代码,发现反向边的费用没有改!

于是改动:想到反向边的本质是提供懊悔机会,而我控制的是每次增长一个单位!懊悔一次的话,必定是付上一次的费用!

所以,与平时不同:初始化反向边费用也为W(不是-W)。每次增广改动为-1a.-3a.-5a,这样控制比正向边慢一步。(事实上这才是反向边的本质作用,仅仅是平时时候费用是不变的,所以无需如此!)提交后AC!

(ps:感觉对费用流算法内部逻辑更加清晰了有木有)

后来看了网上的题解:看数据流量为<5,所以每条边拆为流量为1的,每条费用也如此递增。其次,这样本质是还是每次增广流量1,可谓异曲同工。

只是拆边的思想值得借鉴。

额外收获:1:注意看数据范围,有时候能够从上面思考算法。2:写程序前先过一遍例子,也许有思路启示。

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<queue>
  4. #include<cstring>
  5. using namespace std;
  6. const int maxv=200;
  7. const int maxe=5000*2*2;
  8. const int inf=0x3f3f3f3f;
  9. int nume=0;int e[maxe][5];int head[maxv];
  10. int n,m,k;
  11. void inline adde(int i,int j,int c,int w,int f) //新加入一个參数f,记录初始费用。费用w改变
  12. {
  13. e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
  14. e[nume][2]=c;e[nume][3]=w;e[nume++][4]=f;
  15. e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
  16. e[nume][2]=0;e[nume][3]=w;e[nume++][4]=f;
  17. }
  18. int inq[maxv];int pre[maxv];int prv[maxv];
  19. int d[maxv];
  20. bool spfa(int &sum,int &flow)
  21. {
  22. int s=0,t=n+1;
  23. for(int i=0;i<=n+3;i++)
  24. {
  25. inq[i]=0;
  26. d[i]=inf;
  27. }
  28. queue<int>q;
  29. q.push(s);
  30. inq[s]=1;
  31. d[s]=0;
  32. while(!q.empty())
  33. {
  34. int cur=q.front();
  35. q.pop();
  36. inq[cur]=0;
  37. for(int i=head[cur];i!=-1;i=e[i][1])
  38. {
  39. int v=e[i][0];
  40. if(e[i][2]>0&&d[cur]+e[i][3]<d[v])
  41. {
  42. d[v]=d[cur]+e[i][3];
  43. pre[v]=i;
  44. prv[v]=cur;
  45. if(!inq[v])
  46. {
  47. q.push(v);
  48. inq[v]=1;
  49. }
  50. }
  51. }
  52. }
  53. if(d[t]==inf)return 0;
  54. int cur=t;
  55. int minf=1; //每次增广一个单位
  56. while(cur!=s)
  57. {
  58. int fe=pre[cur];
  59. e[fe][3]+=e[fe][4]*2; //关键点。
  60. e[fe^1][3]-=e[fe][4]*2; //比正向边慢一步更新。(初始值来控制)
  61. cur=prv[cur];
  62. }
  63. cur=t;
  64. while(cur!=s)
  65. {
  66. e[pre[cur]][2]-=minf;
  67. e[pre[cur]^1][2]+=minf;
  68. cur=prv[cur];
  69. }
  70. flow+=minf;
  71. sum+=d[t]; //,每次一单位,不用说,最短路即为总费用
  72. return 1;
  73. }
  74. int mincost(int &flow)
  75. {
  76. int sum=0;
  77. while(spfa(sum,flow));
  78. return sum;
  79. }
  80. void init()
  81. {
  82. nume=0;
  83. for(int i=0;i<=n+2;i++)
  84. head[i]=-1;
  85. }
  86. int main()
  87. {
  88. while(~scanf("%d%d%d",&n,&m,&k))
  89. {
  90. init();
  91. int a,b,x,c;
  92. for(int j=0;j<m;j++)
  93. {
  94. scanf("%d%d%d%d",&a,&b,&x,&c);
  95. adde(a,b,c,x,x);
  96. }
  97. adde(0,1,k,0,0);
  98. adde(n,n+1,k,0,0); //附加边来推断流量满否,方便
  99. int flow=0;
  100. int ans=mincost(flow);
  101. if(flow!=k)
  102. printf("-1\n");
  103. else printf("%d\n",ans);
  104. }
  105. return 0;
  106. }

hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流的更多相关文章

  1. hdu 4548 第六周H题(美素数)

    第六周H题 - 数论,晒素数 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   De ...

  2. hdu 4460 第37届ACM/ICPC杭州赛区H题 STL+bfs

    题意:一些小伙伴之间有朋友关系,比如a和b是朋友,b和c是朋友,a和c不是朋友,则a和c之间存在朋友链,且大小为2,给出一些关系,求出这些关系中最大的链是多少? 求最短路的最大距离 #include& ...

  3. 2017北京赛区H题

    题目链接 题意:在n*m的矩阵中选择变换或者不变换一个数变成p,使得最大子矩阵和最小 1<=n,m<=150, -1000<=p<=1000; 题解: 他人题解链接 涉及到知识 ...

  4. zoj 3662 第37届ACM/ICPC长春赛区H题(DP)

    题目:给出K个数,使得这K个数的和为N,LCM为M,问有多少种 f[i][j][k]表示选i个数,总和为j,最小公倍数为k memery卡的比较紧,注意不要开太大,按照题目数据开 这种类型的dp也是第 ...

  5. 2013年 ACMICPC 杭州赛区H题

    思路:树状数组统计.待验证,不知道是否对. #include<cstdio> #include<cstring> #include<cmath> #include& ...

  6. HDU 3667 Transportation(网络流之费用流)

    题目地址:HDU 3667 这题的建图真是巧妙...为了保证流量正好达到k.须要让每一次增广到的流量都是1,这就须要把每一条边的流量都是1才行.可是每条边的流量并非1,该怎么办呢.这个时候能够拆边,反 ...

  7. HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)

    HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...

  8. HDU 3667 费用流 拆边 Transportation

    题意: 有N个城市,M条有向道路,要从1号城市运送K个货物到N号城市. 每条有向道路<u, v>运送费用和运送量的平方成正比,系数为ai 而且每条路最多运送Ci个货物,求最小费用. 分析: ...

  9. HDU 3667.Transportation 最小费用流

    Transportation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

随机推荐

  1. PHP AES128加密解密

    <?php /** * Class AES */ class AES { public static function encrypt($input, $key) { $size = mcryp ...

  2. linxu安装方式

    安装Linux操作系统的5种方法以及心得这几天没有调别的东西,想起自己还不太会在没有安装光盘的时候安装Linux,于是试了一下Linux的五种安装方法,下面是我的一些 篇一:安装Linux操作系统的5 ...

  3. (二十七)Linux的inode的理解

    一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...

  4. 无类型指针 在delphi中可以直接赋值任何指针类型。

  5. IIS——MIME介绍与添加MIME类型

    MIME(MultipurposeInternet Mail Extensions)多用途互联网邮件扩展类型.是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会 ...

  6. Codeforces Round #503 (by SIS, Div. 2) C. Elections(枚举,暴力)

    原文地址 C. Elections time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  7. Tarjan缩点【p4819】[中山市选]杀人游戏

    Description 一位冷血的杀手潜入Na-wiat,并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀 ...

  8. Linux是32位还是64位

    命令行输入 file /bin/ls 显示 /sbin/init: ELF 64-bit LSB executable, x86-64 ...   则为64位 file /sbin/init /sbi ...

  9. 线程流量控制工具之Semaphore

    简介 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源.很多年以来,我都觉得从字面上很难理解Semaphore所表达的含义,只能把它比作是 ...

  10. JavaScrip book

     1.<JavaScript: The Good Parts>中文版:<JavaScript语言精粹>2.<Professional JavaScript for Web ...