首页 > 代码库 > HDU1565_方格取数(1)
HDU1565_方格取数(1)
给一个数字方阵,你要从中间取出一些数字,保证相邻的两个数字不同时被取出来,求取出来的最大的和是多少?
建立图模型,对于行列的和为奇数的格子,建立一条从原点到达这个点的边,对于行列和为偶数的格子,建立一条从该点到汇点的边,流量均为这个数;对于相邻的格子,建立一条无穷大流量的边,这样要求最大的独立和,我们只要把最小割求出来,总和减去这个最小割就是我们的答案了呢。(EK也不会T哦)
召唤代码君:
#include <iostream>#include <cstdio>#include <cstring>#define maxn 555#define Inf 9999999using namespace std;int c[maxn][maxn],tag[maxn],pre[maxn],f[maxn];int a[maxn][maxn];int n,m,s,t,ans,tot,N=99;int Q[maxn],bot,top;void _init(){ s=0,t=n*n+1,ans=tot=0; memset(c,0,sizeof c);}void graph(){ for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) if ((i+j)%2==1) { int cur=i*n+j-n; c[s][cur]+=a[i][j]; if (i>1) c[cur][cur-n]+=Inf; if (i<n) c[cur][cur+n]+=Inf; if (j>1) c[cur][cur-1]+=Inf; if (j<n) c[cur][cur+1]+=Inf; } else c[i*n+j-n][t]+=a[i][j];}int EK(){ N++; Q[bot=top=1]=s,f[s]=Inf,tag[s]=N; while (bot<=top) { int cur=Q[bot++]; for (int i=s; i<=t; i++) if (c[cur][i]>0 && tag[i]!=N) { tag[i]=N; pre[i]=cur; f[i]=min(f[cur],c[cur][i]); Q[++top]=i; if (i==t) { for (int k=t; k!=s; k=pre[k]) c[pre[k]][k]-=f[t],c[k][pre[k]]+=f[t]; return f[t]; } } } return 0;}int main(){ while (scanf("%d",&n)!=EOF) { _init(); for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) scanf("%d",&a[i][j]),tot+=a[i][j]; graph(); while (int k=EK()) ans+=k; printf("%d\n",tot-ans); } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。