hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流
题意: 在一般费用流题目改动:路过某路,每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:写程序前先过一遍例子,也许有思路启示。
- #include<cstdio>
- #include<iostream>
- #include<queue>
- #include<cstring>
- using namespace std;
- const int maxv=200;
- const int maxe=5000*2*2;
- const int inf=0x3f3f3f3f;
- int nume=0;int e[maxe][5];int head[maxv];
- int n,m,k;
- void inline adde(int i,int j,int c,int w,int f) //新加入一个參数f,记录初始费用。费用w改变
- {
- e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
- e[nume][2]=c;e[nume][3]=w;e[nume++][4]=f;
- e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
- e[nume][2]=0;e[nume][3]=w;e[nume++][4]=f;
- }
- int inq[maxv];int pre[maxv];int prv[maxv];
- int d[maxv];
- bool spfa(int &sum,int &flow)
- {
- int s=0,t=n+1;
- for(int i=0;i<=n+3;i++)
- {
- inq[i]=0;
- d[i]=inf;
- }
- queue<int>q;
- q.push(s);
- inq[s]=1;
- d[s]=0;
- while(!q.empty())
- {
- int cur=q.front();
- q.pop();
- inq[cur]=0;
- for(int i=head[cur];i!=-1;i=e[i][1])
- {
- int v=e[i][0];
- if(e[i][2]>0&&d[cur]+e[i][3]<d[v])
- {
- d[v]=d[cur]+e[i][3];
- pre[v]=i;
- prv[v]=cur;
- if(!inq[v])
- {
- q.push(v);
- inq[v]=1;
- }
- }
- }
- }
- if(d[t]==inf)return 0;
- int cur=t;
- int minf=1; //每次增广一个单位
- while(cur!=s)
- {
- int fe=pre[cur];
- e[fe][3]+=e[fe][4]*2; //关键点。
- e[fe^1][3]-=e[fe][4]*2; //比正向边慢一步更新。(初始值来控制)
- cur=prv[cur];
- }
- cur=t;
- while(cur!=s)
- {
- e[pre[cur]][2]-=minf;
- e[pre[cur]^1][2]+=minf;
- cur=prv[cur];
- }
- flow+=minf;
- sum+=d[t]; //,每次一单位,不用说,最短路即为总费用
- return 1;
- }
- int mincost(int &flow)
- {
- int sum=0;
- while(spfa(sum,flow));
- return sum;
- }
- void init()
- {
- nume=0;
- for(int i=0;i<=n+2;i++)
- head[i]=-1;
- }
- int main()
- {
- while(~scanf("%d%d%d",&n,&m,&k))
- {
- init();
- int a,b,x,c;
- for(int j=0;j<m;j++)
- {
- scanf("%d%d%d%d",&a,&b,&x,&c);
- adde(a,b,c,x,x);
- }
- adde(0,1,k,0,0);
- adde(n,n+1,k,0,0); //附加边来推断流量满否,方便
- int flow=0;
- int ans=mincost(flow);
- if(flow!=k)
- printf("-1\n");
- else printf("%d\n",ans);
- }
- return 0;
- }
hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流的更多相关文章
- hdu 4548 第六周H题(美素数)
第六周H题 - 数论,晒素数 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u De ...
- hdu 4460 第37届ACM/ICPC杭州赛区H题 STL+bfs
题意:一些小伙伴之间有朋友关系,比如a和b是朋友,b和c是朋友,a和c不是朋友,则a和c之间存在朋友链,且大小为2,给出一些关系,求出这些关系中最大的链是多少? 求最短路的最大距离 #include& ...
- 2017北京赛区H题
题目链接 题意:在n*m的矩阵中选择变换或者不变换一个数变成p,使得最大子矩阵和最小 1<=n,m<=150, -1000<=p<=1000; 题解: 他人题解链接 涉及到知识 ...
- zoj 3662 第37届ACM/ICPC长春赛区H题(DP)
题目:给出K个数,使得这K个数的和为N,LCM为M,问有多少种 f[i][j][k]表示选i个数,总和为j,最小公倍数为k memery卡的比较紧,注意不要开太大,按照题目数据开 这种类型的dp也是第 ...
- 2013年 ACMICPC 杭州赛区H题
思路:树状数组统计.待验证,不知道是否对. #include<cstdio> #include<cstring> #include<cmath> #include& ...
- HDU 3667 Transportation(网络流之费用流)
题目地址:HDU 3667 这题的建图真是巧妙...为了保证流量正好达到k.须要让每一次增广到的流量都是1,这就须要把每一条边的流量都是1才行.可是每条边的流量并非1,该怎么办呢.这个时候能够拆边,反 ...
- HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)
HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...
- HDU 3667 费用流 拆边 Transportation
题意: 有N个城市,M条有向道路,要从1号城市运送K个货物到N号城市. 每条有向道路<u, v>运送费用和运送量的平方成正比,系数为ai 而且每条路最多运送Ci个货物,求最小费用. 分析: ...
- HDU 3667.Transportation 最小费用流
Transportation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- PHP AES128加密解密
<?php /** * Class AES */ class AES { public static function encrypt($input, $key) { $size = mcryp ...
- linxu安装方式
安装Linux操作系统的5种方法以及心得这几天没有调别的东西,想起自己还不太会在没有安装光盘的时候安装Linux,于是试了一下Linux的五种安装方法,下面是我的一些 篇一:安装Linux操作系统的5 ...
- (二十七)Linux的inode的理解
一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...
- 无类型指针 在delphi中可以直接赋值任何指针类型。
- IIS——MIME介绍与添加MIME类型
MIME(MultipurposeInternet Mail Extensions)多用途互联网邮件扩展类型.是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会 ...
- 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 ...
- Tarjan缩点【p4819】[中山市选]杀人游戏
Description 一位冷血的杀手潜入Na-wiat,并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀 ...
- Linux是32位还是64位
命令行输入 file /bin/ls 显示 /sbin/init: ELF 64-bit LSB executable, x86-64 ... 则为64位 file /sbin/init /sbi ...
- 线程流量控制工具之Semaphore
简介 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源.很多年以来,我都觉得从字面上很难理解Semaphore所表达的含义,只能把它比作是 ...
- JavaScrip book
1.<JavaScript: The Good Parts>中文版:<JavaScript语言精粹>2.<Professional JavaScript for Web ...