您的位置:首页 > 其它

POJ 3422 Kaka's Matrix Travels(最小费用最大流)

2014-02-11 16:52 309 查看
http://poj.org/problem?id=3422

题意 : 给你一个N*N的方格,每个格子有一个数字,让你从左上角开始走,只能往下往右走,走过的数字变为0,走K次,问最大能是多大,累加的。

思路 :http://blog.csdn.net/qq172108805/article/details/7857503,这道题挺难的,我也是看的题解。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <stdlib.h>
#include <algorithm>

using namespace std;

const int maxn = 5050 ;
const int INF = 1000000000 ;
const int maxm = 110000 ;

struct node
{
int u,v,c,f,b,next ;
}map[maxm] ;
bool flag[maxn] ;
int cap[55][55],dist[maxn],pre[maxn],head[maxn] ;
int s,t,n,k,ans,cnt ;
int del,val ;

void addedge(int u,int v,int c,int b)
{
map[cnt].u = u ;
map[cnt].v = v ;
map[cnt].c = c ;
map[cnt].b = b ;
map[cnt].f = 0 ;
map[cnt].next = head[u] ;
head[u] = cnt++ ;

map[cnt].u = v ;
map[cnt].v = u ;
map[cnt].c = 0 ;
map[cnt].b = -b ;
map[cnt].f = 0 ;
map[cnt].next = head[v] ;
head[v] = cnt++ ;
}

void spfa()
{
memset(flag,0,sizeof(flag)) ;
queue<int >Q ;
Q.push(s) ;
flag[s] = true ;
while(!Q.empty())
{
int x = Q.front() ;
Q.pop() ;
flag[x] = false ;
for(int i = head[x] ; i+1 ; i = map[i].next)
{
int y = map[i].v ;
if(map[i].c > map[i].f && dist[y] < dist[x] + map[i].b)
{
dist[y] = dist[x]+map[i].b ;
pre[y] = i ;
if(!flag[y])
{
flag[y] = true ;
Q.push(y) ;
}
}
}
}
}

void mcmf()
{
for( ; ; )
{
memset(dist,-1,sizeof(dist)) ;
memset(pre,-1,sizeof(pre)) ;
dist[s] = 0 ;
spfa() ;
if(dist[t] == -1)
break ;
int minn = INF ;
for(int i = pre[t] ; i+1 ; i = pre[map[i].u])
minn = min(minn,map[i].c-map[i].f) ;
for(int i = pre[t] ; i+1 ; i = pre[map[i].u])
{
map[i].f += minn ;
map[i^1].f -= minn ;
}
ans += dist[t] ;
}
}

void Init()
{
cnt = 0 ;
memset(head,-1,sizeof(head)) ;
s = 0 ;
t = 2*n*n+1 ;
del = n*n ;
ans = 0 ;
}
int main()
{
scanf("%d %d",&n,&k) ;
Init() ;
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= n ; j++)
scanf("%d",&cap[i][j]) ;
}
addedge(s,1,k,0) ;
addedge(n*n+del,t,k,0) ;
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= n ; j++)
{
val = (i-1)*n+j ;
addedge(val,val+del,1,cap[i][j]) ;
addedge(val,val+del,INF,0) ;
if(j != n) addedge(val+del,val+1,INF,0) ;
if(i < n) addedge(val+del,val+n,INF,0) ;
}
}
mcmf() ;
printf("%d\n",ans) ;
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: