您的位置:首页 > 其它

Codevs 1227方格取数 (费用流

2017-06-10 10:24 330 查看

1227 方格取数 2

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 大师 Master



题目描述 Description

给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大

输入描述 Input Description

第一行两个数n,k(1<=n<=50, 0<=k<=10)

接下来n行,每行n个数,分别表示矩阵的每个格子的数

输出描述 Output Description


4000
个数,为最大和

样例输入 Sample Input

3 1

1 2 3

0 2 1

1 4 2

样例输出 Sample Output

11

数据范围及提示 Data Size & Hint

1<=n<=50, 0<=k<=10

题解: 最大费用最大流 第一次做 其实还是不太会,建图好麻烦QAQ,每个点之间连两条边 一条容量为1,费用为val,另一条容量为INF,费用为0.

贴上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int n,k,maxn;
int next[20000],point[10000],cost[20000],remain[20000],v[20000],tot=-1;
int dis[10000],laste[10000],can[10000];
const int inf=1e9;
void add(int x,int y,int z,int q)
{
tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=z; cost[tot]=q;
tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0; cost[tot]=-q;
}
int addflow(int s,int t)
{
int minn=inf; int now=t;
while(now!=s)
{
minn=min(minn,remain[laste[now]]);
now=v[laste[now]^1];
}
now=t;
while(now!=s)
{
remain[laste[now]]-=minn;
remain[laste[now]^1]+=minn;
now=v[laste[now]^1];
}
return minn;
}
bool spfa(int s,int t)
{
for (int i=s;i<=t;i++)
dis[i]=-inf;
memset(can,0,sizeof(can));
dis[s]=0; can[s]=1;
queue<int> p; p.push(s);
while(!p.empty())
{
int now=p.front(); p.pop();
for (int i=point[now];~i;i=next[i])
if (dis[v[i]]<dis[now]+cost[i]&&remain[i])
{
dis[v[i]]=dis[now]+cost[i];
laste[v[i]]=i;
if (!can[v[i]])
{
can[v[i]]=1;
p.push(v[i]);
}
}
can[now]=0;
}
if (dis[t]<0)  return false;
maxn+=addflow(s,t)*dis[t];
return true;
}
void maxflow(int s,int t)
{
while (spfa(s,t));
}
int main()
{
memset(next,-1,sizeof(next));
memset(point,-1,sizeof(point));
scanf("%d%d",&n,&k);
int num=n*n;
int sum=0;
add(0,1,k,0);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
sum++;
int x; scanf("%d",&x);
add(sum,sum+num,inf,0),add(sum,sum+num,1,x);
if (j!=n)
add(sum+num,sum+1,inf,0);
if (i!=n)
add(sum+num,sum+n,inf,0);
}
add(num*2,num*2+1,k,0);
maxn=0;
maxflow(0,num*2+1);
printf("%d\n",maxn);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: