您的位置:首页 > 其它

hdu1569 方格取数(2) (最大流 E_K)模板 邻接表

2012-07-18 23:35 411 查看

方格取数(2)

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2580 Accepted Submission(s): 777


[align=left]Problem Description[/align]
给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。

[align=left]Input[/align]
包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)

[align=left]Output[/align]
对于每个测试实例,输出可能取得的最大的和

[align=left]Sample Input[/align]

3 3
75 15 21
75 15 28
34 70 5

[align=left]Sample Output[/align]

188

心得:卡了好久就是把 n与m 搞混了 = =!!!
vector邻接表实现 E_K

View Code

#include<iostream>
#include<cstdio>
#include<fstream>
#include<cstring>
#include<vector>
#include<queue>
#define INF 2<<27
#define N 2510

using namespace std;

struct edge{int v,w;};
vector<edge>e
;
int aa[55][55],flow

,p
,a
;

void build_map(int n,int m)
{
int i,j,u;
edge t;
for(i=0;i<N;i++) e[i].clear(); //在这忘了初始化
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if((i+j)%2==0)
{
t.v=(i-1)*m+j;t.w=aa[i][j];
e[0].push_back(t);
}
else
{
u=(i-1)*m+j;
t.v=n*m+1;t.w=aa[i][j];
e[u].push_back(t);
}
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if((i+j)%2==0)
{
u=(i-1)*m+j;
if(j<m)
{
t.v=u+1;t.w=INF;
e[u].push_back(t);
t.v=u;t.w=0;
e[u+1].push_back(t);
}
if(j>1)
{
t.v=u-1;t.w=INF;
e[u].push_back(t);
t.v=u;t.w=0;
e[u-1].push_back(t);
}
if(i>1)
{
t.v=u-m;t.w=INF;
e[u].push_back(t);
t.v=u;t.w=0;
e[u-m].push_back(t);
}
if(i<n)
{
t.v=u+m;t.w=INF;
e[u].push_back(t);
t.v=u;t.w=0;
e[u+m].push_back(t);
}
}
}
}
}

int E_K(int s,int t)
{
int u,v,w,f=0;
memset(flow,0,sizeof(flow));
queue<int>Q;
while(true)
{
memset(a,0,sizeof(a));
a[s]=INF;
Q.push(s);
while(!Q.empty())
{
u=Q.front();Q.pop();
vector<edge>::iterator it;
for(it=e[u].begin();it<e[u].end();it++)
{
v=it->v;w=it->w;
if(!a[v] && w>flow[u][v])
{
a[v]=(a[u]<w-flow[u][v]?a[u]:w-flow[u][v]);
p[v]=u;
Q.push(v);
}
}
}
if(a[t]==0) break;
f+=a[t];
for(u=t;u!=s;u=p[u])
{
flow[p[u]][u]+=a[t];
flow[u][p[u]]-=a[t];
}
}
return f;
}

int main()
{
int i,j,n,m,sum;
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while(cin>>n>>m)
{
sum=0;
memset(aa,0,sizeof(aa));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&aa[i][j]);
sum+=aa[i][j];
}
}
build_map(n,m);
printf("%d\n",sum-E_K(0,n*m+1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: