HIT 2715 Matrix3(最大费用最大流)

Matrix3

My Tags   (Edit)
  Source : bin3
  Time limit : 5 sec   Memory limit : 64 M

Submitted : 302, Accepted : 74

Zhouguyue is a "驴友" and nowadays he likes traveling on an N * N matrix with a non-negative number in each grid, and each grid has a height. Zhouguyue starts his matrix travel with POINT = 0. For each travel, zhouguyue can land on any grid he wants with the help of bin3's helicopter, and then he can only move to ajacent grids whose height is less than his current height. Notice that when he is at the side of the matrix, he can also move out of the matrix. After he moves out of the matrix, he completes one travel. He adds the number in each grid he visited to POINT, and replaces it with zero. Now zhouguyue is wondering what is the maximum POINT he can obtain after he travels at most K times. Note the POINT is accumulative during the travels.

Input

The first line is a integer T indicating the number of test cases.T cases fllows. The first line of each case contains two integers N and K (1 ≤ N ≤ 50, 0 ≤ K ≤ 50) described above. The following N lines represents the matrix. You can assume the numbers in the matrix are non-negative integers and no more than 10000. The following N lines represents the height of each grid. The heghts are also non-negative integers.

Output

The maximum POINT zhouguyue can obtain after he travels at most K times.

Sample Input

1
3 2
1 2 3
3 2 1
2 4 2

3 5 3
2 1 0
1 2 3

Sample Output

17

题目:http://acm.hit.edu.cn/hoj/problem/view?id=2715

题意:就是一个矩阵,每次你可以任意选一个格子,然后可以跳到相邻的比他低的格子上去,每个格子里有分数,问连续k次能得到的分数和最大值。。。

分析:很明显的最大费用最大流。。。首先肯定要分点,把每个格子分成两个点,这两个点之间要连两条边,一条容量为1,费用为格子分数的相反数(转换为最小费用流),另一条边容量为无穷,费用为0(以下的边都是这样的边),表示格子可以多次通过,然后就是对于相邻的格子并满足条件的,也要连上一条边,注意点的分层,然后就是虚构出三个点,一个汇点,在矩阵边缘的格子都有连上她,一个源点,连到每个格子,一个总源点,连到源点,这条边要求容量为k就行了。。。

然后套模板。。。1Y

貌似hit的题很少人刷的样子,我居然是最快的- -


代码:

#include<cstdio>
#include<iostream>
using namespace std;
const int mm=66666;
const int mn=5555;
const int oo=1e9;
int src,dest,node,edge;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
int ver[mm],cost[mm],flow[mm],next[mm];
int head[mn],dis[mn],p[mn],q[mn];
int h[55][55];
bool vis[mn]={0};
void prepare(int _node,int _src,int _dest)
{
    node=_node,src=_src,dest=_dest;
    for(int i=0;i<node;++i)head[i]=-1;
    edge=0;
}
void addedge(int u,int v,int f,int c)
{
    ver[edge]=v,flow[edge]=f,cost[edge]=c,next[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,cost[edge]=-c,next[edge]=head[v],head[v]=edge++;
}
bool Spfa()
{
    int i,u,v,l,r=0,tmp;
    for(i=0;i<node;++i)dis[i]=oo;
    dis[q[r++]=src]=0;
    p[src]=p[dest]=-1;
    for(l=0;l!=r;(++l==mn)?l=0:l)
        for(i=head[u=q[l]],vis[u]=0;i>=0;i=next[i])
            if(flow[i]&&dis[v=ver[i]]>(tmp=dis[u]+cost[i]))
            {
                dis[v]=tmp;
                p[v]=i^1;
                if(vis[v])continue;
                vis[q[r++]=v]=1;
                if(r==mn)r=0;
            }
    return p[dest]>-1;
}
int Spfaflow()
{
    int i,delta,ret=0;
    while(Spfa())
    {
        for(i=p[dest],delta=oo;i>=0;i=p[ver[i]])
            if(flow[i^1]<delta)delta=flow[i^1];
        for(i=p[dest];i>=0;i=p[ver[i]])
            flow[i]+=delta,flow[i^1]-=delta;
        ret-=delta*dis[dest];
    }
    return ret;
}
int main()
{
    int i,j,x,y,k,n,m,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        prepare(n*n*2+3,n*n*2+1,n*n*2+2);
        for(i=0;i<n;++i)
            for(j=1;j<=n;++j)
            {
                scanf("%d",&k);
                addedge(0,i*n+j,oo,0);
                addedge(i*n+j,n*n+i*n+j,1,-k);
                addedge(i*n+j,n*n+i*n+j,oo,0);
            }
        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j)
                scanf("%d",&h[i][j]);
        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j)
                for(k=0;k<4;++k)
                {
                    x=i+dx[k];
                    y=j+dy[k];
                    if(x<1||x>n||y<1||y>n||h[x][y]>=h[i][j])continue;
                    addedge(n*n+i*n-n+j,x*n-n+y,oo,0);
                }
        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j)
                if(i==1||j==1||i==n||j==n)
                    addedge(n*n+n*i-n+j,dest,oo,0);
        addedge(src,0,m,0);
        printf("%d\n",Spfaflow());
    }
    return 0;
}



你可能感兴趣的:(Integer,OO,each,Matrix,output,Numbers)