hdu 3667(2010年哈尔滨现场赛1008题)
2011-09-17 10:45
232 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667
题意描述:一个人携带k单位的东西要从城市1安全到达n,有m条有向的路径连接这n个城市,该人从每条路上经过时可能会遇到劫匪,那么这条路的危险系数为a,那么他要安全的经过该条路径,就需要花a*x*x的费用去雇佣guard(这里x表示该人携带的多少单位的物品),且每条路径上的最多可以携带c单位的物品通过(注意这里c<=5),现在要求最少的费用使他能够安全到达n,若不能到达则输出-1;
分析:该题是显然的费用流题目的变形,因为这里容量变成了x*x了,那么这就用最小费流求出来的值将是错误的,因为2*2!=1*1+1*1的,所以这里我就想到了这些走过的边必须得整体考虑,这里我就先用费用流求出了最大流,让后再在结果中寻找容量改变了的边,然后计算出中的花费,显然这也是错误的,因为第三个样例就果断悲剧了,因为该人走的时候每次并不是选择单位费用最少的那条路走,而是要选择c*x*x的最小的那条边走,所以这样求出来的值是错的,这时候我猛然发现c<=5这个条件没有用,这里我就想到了拆边,若要体现每次都是选择都是在前面选择的基础上进行的,每次求的增广路都是c*x*x代表的权值中最小的,那么基本思路就出来了,将每条容量为w的边拆成容量为1的w条边,这里费用为0的边,只需要建一条边即可,因为这条边不管携带多少单位的东西经过不需要任何费用也是安全的,最后新建一个源点和节点1相连容量为k,费用为0,那么求最小费用最大流即是解,现在剩下的问题就是权值问题了,刚开始我将每条拆开的权值设为c*j*j,这样建图之后用费用流求出最大流后,先判断是否能全部运过去,这里原先有m条边,那么就被拆成了m组边,我想用最小费用流之后在每一组边中找到容量为0且费用最高的那条边然后每组求和,这样也是错的,因为当用最短路进行增广的时候,选择路径的时候就可能不是最好的,因为该边开始已径流过i次了,那么第i+1次流过的费用就应该是(i+1)^2-(i*i),但是我这里的权值却是(i+1)^2,那么在选择路径增广的时候就有可能出现两条边的x*x+y*y<(i+1)^2但是(x*x)-(x-1)^2+(y*y)-(y-1)^(y-1)>(i+1)^2-(i*i),那么这个时候选择错误!!!!!
建图的方法: 新建源点,源点到1连边容量为k,费用为0,将给出的每条边拆成w条容量为1的边每一条的费用为((i+1)^2-(i*i))*c=(2*i-1)*c,费用为0的边不需要拆边,那么这样建图之后求最小费最大流即可,若最大流<k那么表示不能够到达n,则输出-1,否则输出最小费用,注意这里当k=0时,假如图不是连通的,那么则应该输出-1,但是按以上方法输出的为0,我试了一下没有这样的数据!!
代码如下:
题意描述:一个人携带k单位的东西要从城市1安全到达n,有m条有向的路径连接这n个城市,该人从每条路上经过时可能会遇到劫匪,那么这条路的危险系数为a,那么他要安全的经过该条路径,就需要花a*x*x的费用去雇佣guard(这里x表示该人携带的多少单位的物品),且每条路径上的最多可以携带c单位的物品通过(注意这里c<=5),现在要求最少的费用使他能够安全到达n,若不能到达则输出-1;
分析:该题是显然的费用流题目的变形,因为这里容量变成了x*x了,那么这就用最小费流求出来的值将是错误的,因为2*2!=1*1+1*1的,所以这里我就想到了这些走过的边必须得整体考虑,这里我就先用费用流求出了最大流,让后再在结果中寻找容量改变了的边,然后计算出中的花费,显然这也是错误的,因为第三个样例就果断悲剧了,因为该人走的时候每次并不是选择单位费用最少的那条路走,而是要选择c*x*x的最小的那条边走,所以这样求出来的值是错的,这时候我猛然发现c<=5这个条件没有用,这里我就想到了拆边,若要体现每次都是选择都是在前面选择的基础上进行的,每次求的增广路都是c*x*x代表的权值中最小的,那么基本思路就出来了,将每条容量为w的边拆成容量为1的w条边,这里费用为0的边,只需要建一条边即可,因为这条边不管携带多少单位的东西经过不需要任何费用也是安全的,最后新建一个源点和节点1相连容量为k,费用为0,那么求最小费用最大流即是解,现在剩下的问题就是权值问题了,刚开始我将每条拆开的权值设为c*j*j,这样建图之后用费用流求出最大流后,先判断是否能全部运过去,这里原先有m条边,那么就被拆成了m组边,我想用最小费用流之后在每一组边中找到容量为0且费用最高的那条边然后每组求和,这样也是错的,因为当用最短路进行增广的时候,选择路径的时候就可能不是最好的,因为该边开始已径流过i次了,那么第i+1次流过的费用就应该是(i+1)^2-(i*i),但是我这里的权值却是(i+1)^2,那么在选择路径增广的时候就有可能出现两条边的x*x+y*y<(i+1)^2但是(x*x)-(x-1)^2+(y*y)-(y-1)^(y-1)>(i+1)^2-(i*i),那么这个时候选择错误!!!!!
建图的方法: 新建源点,源点到1连边容量为k,费用为0,将给出的每条边拆成w条容量为1的边每一条的费用为((i+1)^2-(i*i))*c=(2*i-1)*c,费用为0的边不需要拆边,那么这样建图之后求最小费最大流即可,若最大流<k那么表示不能够到达n,则输出-1,否则输出最小费用,注意这里当k=0时,假如图不是连通的,那么则应该输出-1,但是按以上方法输出的为0,我试了一下没有这样的数据!!
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const __int64 N=200; const __int64 E=60000; const __int64 inf=0x3fffffffffffff; struct node { __int64 x,y,nxt,w; __int64 c; }edge[E]; __int64 head ,e; __int64 Flow,n,Cost; void addedge(__int64 x,__int64 y, __int64 w,__int64 c) { edge[e].x=x; edge[e].y=y; edge[e].w=w; edge[e].c=c; edge[e].nxt=head[x]; head[x]=e++; edge[e].x=y; edge[e].y=x; edge[e].w=0; edge[e].c=-c; edge[e].nxt=head[y]; head[y]=e++; } void Maxfminc() { __int64 dist ;__int64 isque ,que ,pre ; __int64 f,r; __int64 i,u; Flow=0;Cost=0; while(1) { f=0,r=1; for(i=0;i<=n;i++) { dist[i]=inf; isque[i]=0; } dist[0]=0; que[0]=0; isque[0]=1; while(f!=r) { u=que[f]; f=(f+1)%N; for(i=head[u];i!=-1;i=edge[i].nxt) { __int64 v=edge[i].y; if(edge[i].w>0&&dist[v]>dist[u]+edge[i].c) { dist[v]=dist[u]+edge[i].c; pre[v]=i; if(!isque[v]) { isque[v]=1; que[r]=v; r=(r+1)%N; } } } isque[u]=0; } if(dist ==inf)break; Flow++; Cost +=dist ; __int64 p; for(u=n;u!=0;u=edge[pre[u]^1].y) { p=pre[u]; edge[p].w-=1; edge[p^1].w+=1; } } } int main () { __int64 i,m,k,j; __int64 x,y,c,w; while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF) { memset(head,-1,sizeof(head)); e=0; for(i=0;i<m;i++) { scanf("%I64d%I64d%I64d%I64d",&x,&y,&c,&w); if(c==0) addedge(x,y,w,0); else { for( j=1;j<=w;j++) addedge(x,y,1,(2*j-1)*c); } } if(k!=0) addedge(0,1,k,0); else addedge(0,1,1,0); Maxfminc(); if(k==0&&Flow==0) { printf("-1\n");continue;} else if(k==0&&Flow==1) {printf("0\n");continue;} if(Flow<k) printf("-1\n"); else printf("%I64d\n",Cost); } return 0; }
相关文章推荐
- hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流
- hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流
- hdu 3666 THE MATRIX PROBLEM //2010哈尔滨现场赛
- HDU 2451(2008哈尔滨现场赛)
- HDU 2454(2008哈尔滨现场赛)
- hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流
- hdu 1008
- HDU - 6201 transaction transaction transaction (2017 ACM-ICPC 亚洲区 (沈阳赛区) 网络赛 1008)
- HDU 5120 Intersection (计算几何)2014ICPC 北京站现场赛
- hdu 3687 10 杭州 现场 H - National Day Parade 水题 难度:0
- HDU 4438 Hunters 第37届ACM/ICPC 天津赛区现场赛H题(超级水的题目)
- hdu(4435)天津现场赛
- 【2017 ACM/ICPC Asia Regional Qingdao Online 1008】hdu 6213 Chinese Zodiac
- hdu 5131 (2014广州现场赛 E题)
- POJ 1008 && HDU 1444 Maya Calendar(历法)
- hdu 4465 Candy(2012 ACM-ICPC 成都现场赛)
- HDU 4777 Rabbit Kingdom (2013杭州赛区1008题,预处理,树状数组)
- HDU 5532 2015ACM-ICPC长春赛区现场赛F题
- hdu 3715(2-sat入门题目)2010成都现场赛1007题
- HDU 5073 Galaxy (2014 ACM/ICPC 鞍山赛区现场赛D题)