博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)...
阅读量:6969 次
发布时间:2019-06-27

本文共 4327 字,大约阅读时间需要 14 分钟。

题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1。(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量)。每个格子走且仅能走一次。

选<=K条路径,最优情况来覆盖全图。

 显然用拆点为二分图。

一种解法:边(流量,费用)

            源点向X部连边(1,0)Y部向汇点连边(1,0)X到Y,若能到,则有边(1,消耗-获得)。关键点(解决每个点都覆盖,恰好起到填补的作用):在X部最上面添加一个点,源点连之(k,0)它向所有Y点连边(1,0)。跑最小费用最大流即可。

第二种:(感想zz1215提供的建图思路)

        源点向X部连边(1,0)Y部向汇点连边(1,0),Y到X,若能到,则有边(1,消耗-获得)(注意这里是回流),每个点I-->I`有边(1,-w_inf),这里的w_inf为相对大数,只要保证该费用较“小”即可(相对其他费用,他是最廉价的,这样必优先流这条边。添加超级源点,向源点连边(K,0)。增广K次中,若一直增大,则取最大,否则到开始下降的时候要BREAK。(先曾后减的)。

PS:开始时候因为定位编号搞错有没有!编号(i,j)=i*m+j,而不是i*n+j!!!

图:

代码:

#include
//24ms#include
#include
#include
#include
using namespace std;int n,m,k;const int inf=0x3f3f3f3f;int a[25][25];int head[500];int e[10000][4];int nume=0;void inline adde(int i,int j,int c,int w){ e[nume][0]=j;e[nume][1]=head[i];head[i]=nume; e[nume][2]=c;e[nume++][3]=w; e[nume][0]=i;e[nume][1]=head[j];head[j]=nume; e[nume][2]=0;e[nume++][3]=-w;}int inq[500];int d[500];bool spfa(int &sumcost) { for(int i=0;i<=2*n*m+3;i++) { inq[i]=0;d[i]=inf; } int minf=inf; queue
q; int prv[300];int pre[300]; q.push(2*n*m+2); inq[2*n*m+2]=1; d[2*n*m+2]=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[v]>e[i][3]+d[cur]) { d[v]=e[i][3]+d[cur]; prv[v]=cur; pre[v]=i; if(!inq[v]) { q.push(v); inq[v]=1; } } } } if(d[2*n*m+1]==inf)return 0; int cur=2*n*m+1; while(cur!=2*n*m+2) { minf=min(minf,e[pre[cur]][2]); cur=prv[cur]; } cur=2*n*m+1; while(cur!=2*n*m+2) { e[pre[cur]][2]-=minf;e[pre[cur]^1][2]+=minf; cur=prv[cur]; } sumcost+=d[2*n*m+1]*minf; return 1;}int mincost(){ int sum=0; while(spfa(sum)); return sum;}void init(){ nume=0; for(int i=0;i<=2*n*m+3;i++) { head[i]=-1; }}int main(){ int T; scanf("%d",&T); for(int iii=1;iii<=T;iii++) { scanf("%d%d%d",&n,&m,&k); init(); string s; for(int i=0;i
>s; for(int j=0;j
k) { printf("-1\n");continue; } for(int i=0;i
%d:c:%d,w:%d\n",i,e[j][0],e[j][2],e[j][3]);*/ printf("%d\n",-mincost()); } return 0;}

方法二:

#include
//31ms#include
#include
#include
using namespace std;int n,m,k;const int inf=0x3f3f3f3f;const int winf=100000; int a[25][25];int head[500];int e[20001][4];int nume=0;void inline adde(int i,int j,int c,int w){ e[nume][0]=j;e[nume][1]=head[i];head[i]=nume; e[nume][2]=c;e[nume++][3]=w; e[nume][0]=i;e[nume][1]=head[j];head[j]=nume; e[nume][2]=0;e[nume++][3]=-w;}int inq[500];int d[500];bool spfa(long long &sumcost){ for(int i=0;i<=2*n*m+3;i++) { inq[i]=0;d[i]=inf; } int prv[500];int pre[500]; int minf=inf; queue
q; q.push(n*m); inq[n*m]=1; d[n*m]=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[v]>e[i][3]+d[cur]) { d[v]=e[i][3]+d[cur]; prv[v]=cur; pre[v]=i; if(!inq[v]) { q.push(v); inq[v]=1; } } } } if(d[2*n*m+1]==inf)return 0; int cur=2*n*m+1; while(cur!=n*m) { minf=min(minf,e[pre[cur]][2]); cur=prv[cur]; } cur=2*n*m+1; while(cur!=n*m) { e[pre[cur]][2]-=minf; e[pre[cur]^1][2]+=minf; cur=prv[cur]; } sumcost+=d[2*n*m+1]*(long long)minf; return 1;}long long mincost(){ long long sum=0; long long lastsum=0; while(spfa(sum)) //变小的时候跳出 { if(lastsum>=-sum){return -lastsum;} lastsum=-sum; } return sum;}void init(){ nume=0; for(int i=0;i<=2*n*m+3;i++) { head[i]=-1; }}int main(){ int T; scanf("%d",&T); for(int iii=1;iii<=T;iii++) { scanf("%d%d%d",&n,&m,&k); init(); string s; for(int i=0;i
>s; for(int j=0;j
k) { printf("-1\n");continue; } for(int i=0;i
%d:c:%d,w:%d\n",i,e[j][0],e[j][2],e[j][3]);*/ cout<<-mincost()-n*m*winf<

转载于:https://www.cnblogs.com/yezekun/p/3925787.html

你可能感兴趣的文章
C#开发中碰到的问题------Uncaught TypeError: Cannot read property 'style' of undefined
查看>>
Android 网络编程
查看>>
正则表达式
查看>>
Tomcat & SVN
查看>>
推荐系统学习03-SVDFeature
查看>>
mysql启动和关闭外键约束的方法
查看>>
安装 Docker <一>
查看>>
C#中的Dictionary字典类介绍
查看>>
PHP 设计模式 笔记与总结(5)PHP 魔术方法的使用
查看>>
Microsoft Visual Studio 下载转帖
查看>>
证券交易买进卖出手续费公式
查看>>
SQL Server存储(6/8) :理解DCM页
查看>>
epoll使用具体解释(精髓)
查看>>
毕业季-回去体检
查看>>
WordPress前台后台页面打开慢的解决方法
查看>>
【m从翻译os文章】写日志禁令Sqlnet.log和Listener.log
查看>>
GRUB启动管理器
查看>>
Maven最佳实践:Maven仓库
查看>>
***PHP多线程pthreads 实现QQ号码爬虫
查看>>
在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView
查看>>