POJ 3422 Kaka's Matrix Travels
来源:互联网 发布:方向余弦矩阵正交证明 编辑:程序博客网 时间:2024/05/24 16:16
费用流问题,只不过这次是最大费用,建边的时候权值取相反数,按最小费用流求完之后在输出负值就行。
题目大意:
Kaka有一个矩阵表格,行从1到n,列从1到n,Kaka从(1,1)开始,向(n,n)走,每一个格子里都有钱w,只能向下或向右走,走到那个格子就可以拿到那个格子里的钱。问走k次最多能拿多少钱。
这个题建图的时候需要拆点。每个格子都是一个点。把一个点拆成两个,两个点之间有两条路,一个容量为1,权值为那个格子的金钱数。另一条路容量为k-1,权值为0。因为走了一次钱捡起来之后就没钱了。
我的代码中为了处理方便,把超级原点设为了n*n*2,超级汇点设为了n*n*2+1。请大家在阅读中注意。
下面是代码:
#include <stdio.h>#include <string.h>#include <queue>using namespace std;const int inf=1<<30,M=5005;int n,m,map1[55][55],head[M],cnt,pre[M],dis[M];bool vis[M];struct node{ int u,v,w,f,next;} edge[100005];int min(int a,int b){ if(a>b) { a=b; } return a;}void add(int u,int v,int w,int f){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt].w=w;//正向边权值为正 edge[cnt].f=f;//正向边流量为f edge[cnt].next=head[u]; head[u]=cnt; cnt++; edge[cnt].u=v; edge[cnt].v=u; edge[cnt].w=-w;//正向边权值为负 edge[cnt].f=0;//流量为零 edge[cnt].next=head[v]; head[v]=cnt; cnt++;}bool spfa() //基于邻接表的SPFA算法{ int i; for(i=0; i<=n*n*2+1; i++) //初始化 { pre[i]=-1; dis[i]=inf; vis[i]=false; } queue <int > q; dis[n*n*2]=0; vis[n*n*2]=true; q.push(n*n*2); while(!q.empty()) { int t=q.front(); q.pop(); i=head[t]; vis[t]=false; while(i!=-1) { if(edge[i].f>0&&dis[edge[i].v]>dis[t]+edge[i].w) { dis[edge[i].v]=dis[t]+edge[i].w; pre[edge[i].v]=i; if(!vis[edge[i].v]) { vis[edge[i].v]=true; q.push(edge[i].v); } } i=edge[i].next; } } if(pre[n*n*2+1]==-1)//如果不在最短路中 代表着最短路寻找失败 { return false; } return true;}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { int i,j; cnt=0; for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { scanf("%d",&map1[i][j]); } } memset(head,-1,sizeof(head)); for(i=1; i<=n; i++) //每一点的拆点建边操作 { for(j=1; j<=n; j++) { int u=(i-1)*n+j-1; add(u*2,u*2+1,-map1[i][j],1); //权值为负值 add(u*2,u*2+1,0,m-1); } } for(i=1; i<=n; i++)//向下移动建边 { for(j=1; j<n; j++) { int u=(i-1)*n+j-1; add(u*2+1,(u+1)*2,0,m); } } for(i=1; i<n; i++)//向右移动建边 { for(j=1; j<=n; j++) { int u=(i-1)*n+j-1; add(u*2+1,(u+n)*2,0,m); } } add(n*n*2,0,0,m);//超级原点建边 add(n*n*2-1,n*n*2+1,0,m);//超级汇点建边 int ans=0; while(spfa()) //如果最短增广路寻找成功 { int max1=inf; int p=pre[n*n*2+1];//初始化P指针 while(p!=-1) //寻找关键流量 { max1=min(max1,edge[p].f); p=pre[edge[p].u]; } p=pre[n*n*2+1]; while(p!=-1) //修改流量 { edge[p].f-=max1; edge[p^1].f+=max1; ans+=max1*edge[p].w; p=pre[edge[p].u]; } } printf("%d\n",-ans); } return 0;}
- poj 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ-3422-Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422:Kaka's Matrix Travels
- poj 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- poj Kaka's Matrix Travels
- poj 3422 Kaka's Matrix Travels 最小费用最大流
- Kaka's Matrix Travels POJ 3422 最大费用流
- POJ 3422 Kaka's Matrix Travels (最大费用最大流)
- POJ 3422 Kaka's Matrix Travels (最大费用最大流)
- POJ 3422 Kaka's Matrix Travels 费用流
- POJ 3422 Kaka's Matrix Travels 最小费用流
- poj-3422-Kaka's Matrix Travels-最小费用最大流
- android monkey script详情
- 切分窗口学习总结及实例
- LeetCode 4Sum
- android中的ellipsize
- Android自动化测试之MonkeyRunner工具(二)
- POJ 3422 Kaka's Matrix Travels
- 在应用层通过spring特性解决数据库读写分离
- highChart另类使用及一些属性
- 完美解决java.lang.OutOfMemoryError: bitmap size exceeds VM budget
- bj
- 安卓自动化测试工具MonkeyRunner之使用ID进行参数化,以及List选择某项和弹出框点击确定的写法
- 算法实验题8.1 黑箱子问题
- 没有applicationi.mk使用ndk-build
- Cocos2d-x 3.0 开发(十二)在CocoStudio中使用粒子挂载与曲线动画