您的位置:首页 > 其它

joj 2656: 霍格瓦兹魔法阵 最小割

2011-09-20 20:00 225 查看
最近,伏地魔开始网罗党羽, 许多女巫和男巫为了获得他赋予的力量加入了他的阵营。为了抵抗伏地魔的进攻,霍格瓦兹的魔法师们摆出了一个 n * m 方格的魔法方阵,每个方格中都站有一位魔法师。 当然,魔法师们都有自己的魔法值,用非负整数表示。 然而,对伏地魔发起攻击时,为了安全起见,任意两个相邻的魔法师 (上下相邻或左右相邻) 不能同时施展魔法。为了打败强大的伏地魔,你能帮助霍格瓦兹的魔法师们找出最大可能的攻击魔法值么?


Input

输入含有多组case 每个case的第一行有两个整数 n 和 m ,代表魔法方阵的规模 接下来输入的是 n * m 的非负整数矩阵。 n和m均不超过50 当n=m=0时,输入结束


Output

对每个case, 输出最大可能魔法值


Input

3 2
1 2
3 4
5 6

3 3
75 15 21
75 15 28
34 70 5

0 0


Output

11
188


//

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

const int N=21010;

const int M=250000;

const int inf=(1<<28);

int head
;

struct Edge

{

int u,v,next,w;

} edge[M];

int cnt,n,s,t;//n从0开始 0->n-1

void addedge(int u,int v,int w)

{

edge[cnt].u=u;

edge[cnt].v=v;

edge[cnt].w=w;

edge[cnt].next=head[u];

head[u]=cnt++;

edge[cnt].u=v;

edge[cnt].v=u;

edge[cnt].w=0;

edge[cnt].next=head[v];

head[v]=cnt++;

}

int sap()

{

int pre
,cur
,dis
,gap
;

int flow=0,aug=inf,u;

bool flag;

for(int i=0; i<n; i++)

{

cur[i]=head[i];

gap[i]=dis[i]=0;

}

gap[s]=n;

u=pre[s]=s;

while(dis[s]<n)

{

flag=0;

for(int &j=cur[u]; j!=-1; j=edge[j].next)

{

int v=edge[j].v;

if(edge[j].w>0&&dis[u]==dis[v]+1)

{

flag=1;

if(edge[j].w<aug) aug=edge[j].w;

pre[v]=u;

u=v;

if(u==t)

{

flow+=aug;

while(u!=s)

{

u=pre[u];

edge[cur[u]].w-=aug;

edge[cur[u]^1].w+=aug;

}

aug=inf;

}

break;

}

}

if(flag) continue;

int mindis=n;

for(int j=head[u]; j!=-1; j=edge[j].next)

{

int v=edge[j].v;

if(edge[j].w>0&&dis[v]<mindis)

{

mindis=dis[v];

cur[u]=j;

}

}

if((--gap[dis[u]])==0)

break;

gap[dis[u]=mindis+1]++;

u=pre[u];

}

return flow;

}

//初始化 cnt=0;memset(head,-1,sizeof(head));

//int u=i+j; u的奇偶性相同则不会相交,否则相交

int xx[4]={0,0,1,-1};

int yy[4]={1,-1,0,0};

int main()

{

int r,c;

while(scanf("%d%d",&r,&c)==2&&r)

{

cnt=0;

memset(head,-1,sizeof(head));

n=r*c+2;

s=0,t=n-1;

int sum=0;

for(int i=1;i<=r;i++)

{

for(int j=1;j<=c;j++)

{

int x;scanf("%d",&x);

sum+=x;

int pos=(i-1)*c+j;

if((i+j)%2)

{

addedge(s,pos,x);

for(int k=0;k<4;k++)

{

int x=i+xx[k],y=j+yy[k];

if(x>=1&&x<=r&&y>=1&&y<=c)

{

addedge(pos,(x-1)*c+y,inf);

}

}

}

else addedge(pos,t,x);

}

}

int ans=sap();

printf("%d\n",sum-ans);

}

return 0;

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