poj3422--Kaka's Matrix Travels(拆点,最大费用)

Kaka‘s Matrix Travels

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7802   Accepted: 3138

Description

On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with
SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking care that the rook moves only to the right or down. Kaka adds the number to
SUM in each grid the rook visited, and replaces it with zero. It is not difficult to know the maximum
SUM Kaka can obtain for his first travel. Now Kaka is wondering what is the maximum
SUM he can obtain after his Kth travel. Note the SUM is accumulative during the
K travels.

Input

The first line contains two integers N and K (1 ≤ N ≤ 50, 0 ≤
K ≤ 10) described above. The following N lines represents the matrix. You can assume the numbers in the matrix are no more than 1000.

Output

The maximum SUM Kaka can obtain after his Kth travel.

Sample Input

3 2
1 2 3
0 2 1
1 4 2

Sample Output

15

要求从左上走到右下,每个权值只能加一次,所以使用拆点,使得每个权值只会使用一次,同样是求最大的权值,所以要是权值为负值。要走k次,所以可以将源点到1和n*n*2到汇点的容量设为k。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 6000
struct node
{
    int v , w , s ;
    int next ;
} p[1000000];
int a[60][60] , cnt ;
int head[maxn] , vis[maxn] , dis[maxn] , pre[maxn] ;
queue <int> q ;
void add(int u,int v,int w,int s)
{
    p[cnt].v = v ;p[cnt].w = w ; p[cnt].s = s ;
    p[cnt].next = head[u] ; head[u] = cnt++;
    p[cnt].v = u ;p[cnt].w = 0 ; p[cnt].s = -s ;
    p[cnt].next = head[v] ; head[v] = cnt++;
}
int spfa(int s,int t)
{
    int u , v , i ;
    memset(dis,INF,sizeof(dis));
    pre[s] = pre[t] = -1 ;
    vis[s] = 1 ;
    dis[s] = 0 ;
    while( !q.empty() )
        q.pop();
    q.push(s) ;
    while( !q.empty() )
    {
        u = q.front();
        q.pop();
        vis[u] = 0 ;
        for(i = head[u] ; i != -1 ; i = p[i].next)
        {
            v=  p[i].v ;
            if( p[i].w && dis[v] > dis[u] + p[i].s)
            {
                dis[v] = dis[u] + p[i].s ;
                pre[v] = i ;
                if( !vis[v] )
                {
                    vis[v] = 1 ;
                    q.push(v);
                }
            }
        }
    }
    if( pre[t] == -1 )
        return 0;
    return 1;
}
void f(int s,int t)
{
    int i , min1 , ans = 0 ;
    memset(pre,-1,sizeof(pre));
    memset(vis,00,sizeof(vis));
    while( spfa(s,t) )
    {
        min1 = INF ;
        for(i = pre[t] ; i != -1 ; i = pre[ p[i^1].v ])
            if( p[i].w < min1 )
                min1 = p[i].w ;
        for(i = pre[t] ; i != -1 ; i = pre[ p[i^1].v ])
        {
            p[i].w -= min1 ;
            p[i^1].w += min1 ;
            ans += p[i].s ;
        }
    }
    printf("%d\n", -ans);
}
int main()
{
    int i , j , n , k , temp , b ;
    while(scanf("%d %d", &n, &k) != EOF)
    {
        /*每个点的值只会被访问一次,所以需要拆点操作,要求的是最大费用,所以可以将费用做成负值,仍可以使用最小费用的做法*/
        cnt = 0 ; temp = n*n ;
        memset(head,-1,sizeof(head));
        for(i = 1 ; i <= n ; i++)
            for(j = 1 ; j <= n ; j++)
            {
                scanf("%d", &a[i][j]);
                b = (i-1)*n + j ;
                add(b,b+temp,1,-a[i][j]);//对于第i个点,由i到i+n*n建边,一条是带有花费的,但容量是1,一条是没花费,容量是k-1,保证一个值只会被访问一次
                add(b,b+temp,k-1,0);
            }
        for(i = 1 ; i <= n ; i++)
        {
            for(j = 1 ; j <= n ; j++)
            {
                b = (i-1)*n+j ;
                if(i >1)
                    add(b-n+temp,b,k,0);
                if(j > 1)
                    add(b-1+temp,b,k,0);
            }
        }
        add(0,1,k,0);//源点是0,汇点是n*n+1
        add(2*temp,2*temp+1,k,0);
        f(0,2*temp+1);
    }
    return 0;
}

poj3422--Kaka's Matrix Travels(拆点,最大费用),布布扣,bubuko.com

poj3422--Kaka's Matrix Travels(拆点,最大费用)

时间: 2024-10-10 11:24:53

poj3422--Kaka's Matrix Travels(拆点,最大费用)的相关文章

POJ3422 Kaka&#39;s Matrix Travels(最大费用最大流 + 拆点)

题目链接:http://poj.org/problem?id=3422 题意:有一个n*n的矩阵,格子中的元素是费用,KaKa从左上角开始出发要到达右下角,但是他只能向下走或者向右走,且走过的格子赋值为0,可以走K次,问K次后KaKa能获得的最大费用是多少? 思路:首先解释一下为什么要拆点?    因为要获得最大费用,所以假设当前步选择先下走,最终得到的结果可能不是最大值,但根据题意却把走过的格子赋为0了,这就影响了最终结果.所以进行拆点,把每个点拆成两个点,入度点和出度点,本点的入度点连接着本

POj3422 Kaka&#39;s Matrix Travels 最小费用最大流 拆点

题目链接: poj3422 题意: 有一个N X N的矩阵, 矩阵的每一小格都有且仅有一个数字v,kaka每经过一个数字就会把它捡起来并将那个数字加到sum上去. 现在kaka能通过向下或向右走的方式从 (1,1)到(n,n)  K次,问kaka能取到的最大的sum是多少. 解题思路: 题目问题可以抽象为   求多次可走重复路的最长路的最大和问题 首先想到的就应该是最小费用最大流, 而题目要求的最大和值,那么应求就是最大费用最大流, 仅仅只需要将代码中的最小路算法改为最长路算法即可 题目的条件是

POJ3422 Kaka&#39;s Matrix Travels[费用流]

Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9522   Accepted: 3875 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka mo

POJ3422 Kaka&#39;s Matrix Travels 【最大费用最大流】

Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8006   Accepted: 3204 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka mo

poj3422 Kaka&#39;s Matrix Travels(最小费用最大流问题)

1 /* 2 poj3422 Kaka's Matrix Travels 3 不知道 k次 dp做为什么不对??? 4 看了大牛的代码,才知道还可以这样做! 5 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序一直陷入死循环,真心花了好长时间,快崩溃了.无语..... 6 题意:有个方阵,每个格子里都有一个非负数,从左上角走到右下角,每次走一步,只能往右或往下走,经过的数字拿走 7 每次都找可以拿到数字和最大的路径走,走k次,求最大和 8 9 这是 最大费用最大流 问题 每次spfa都

POJ3422:Kaka&#39;s Matrix Travels——题解

http://poj.org/problem?id=3422 题目大意: 从左上角走到右下角,中途取数(数>=0),然后该点的数变为0,求走k的总价值和最大值. —————————————————————————————— 最大值?但是我们只会最小费用流啊…… 但是数是>=0的啊,所以…… 我们拆点,中间连一条容量为1费用为当前值负值的边,再连一条容量为k-1费用0的边. 这样就一定会先走前一条边啦! 然后向下向右连一条容量为k费用0的边. 源点到左上角连一条容量为k-1费用0的边. 右下角到

【poj3422】 Kaka&#39;s Matrix Travels

http://poj.org/problem?id=3422 (题目链接) 题意 N*N的方格,每个格子中有一个数,寻找从(1,1)走到(N,N)的K条路径,使得取到的数的和最大. Solution 同[codevs1277] 方格取数 代码 // poj3422 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio>

POJ 3422 Kaka&#39;s Matrix Travels(最大费用最大流 + 拆点)

题目链接:http://poj.org/problem?id=3422 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking

POJ 3422 Kaka&#39;s Matrix Travels(费用流)

POJ 3422 Kaka's Matrix Travels 题目链接 题意:一个矩阵,从左上角往右下角走k趟,每次走过数字就变成0,并且获得这个数字,要求走完之后,所获得数字之和最大 思路:有点类似区间k覆盖的建图方法,把点拆了,每个点有值的只能选一次,其他都是无值的,利用费用流,入点出点之间连一条容量1,有费用的边,和一条容量k - 1,费用0的边,然后其他就每个点和右边和下边2个点连边,然后跑费用流 代码: #include <cstdio> #include <cstring&g

POJ 3422 Kaka&#39;s Matrix Travels

K路最大费用最大流, 每个点的值只能取一次: 拆点,一个点的两个部分之间连 1 条费用mp容量一的边,连一条费用0容量很大的边 K次: 源点和汇点拆点,两个部分之间连K条边 Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7985   Accepted: 3191 Description On an N × N chessboard with a non-negative num