hdu1569-方格取数-二分图网络流
2018-08-23 22:27
453 查看
方格取数(2)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7211 Accepted Submission(s): 2311
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
Input 包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)
Output 对于每个测试实例,输出可能取得的最大的和
Sample Input 3 3 75 15 21 75 15 28 34 70 5
Sample Output 188
Author ailyanlu
Source Happy 2007 把横纵坐标之和按奇偶分成两组,然后对相邻的点连边的话会发现这是一个二分图,我们求得是最大独立集=|V|-最小覆盖集,最小覆盖集可以用网络流来求,左边集合向右边集合的连边容量为inf的边,S向左集合连边,右集合向T连边容量都是格子里的数,然后跑最大流就是 最小覆盖集了。
#include<bits/stdc++.h> using namespace std; #define LL long long #define mp make_pair #define pb push_back #define inf 0x3f3f3f3f #define pii pair<int,int> int first[3030],tot,S,T; int cur[3030],d[3030]; bool vis[3030]; struct Edge{ int v,cap,flow,next; }e[100010]; int fx[4][2]={-1,0,1,0,0,-1,0,1}; void add(int u,int v,int cap){ //cout<<"u="<<u<<' '<<v<<' '<<cap<<endl; e[tot]=Edge{v,cap,0,first[u]}; first[u]=tot++; e[tot]=Edge{u,0,0,first[v]}; first[v]=tot++; } int a[55][55]; bool bfs(){ memset(vis,0,sizeof(vis)); queue<int>q; q.push(0); d[0]=0; vis[0]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=first[u];~i;i=e[i].next){ if(!vis[e[i].v] && e[i].cap>e[i].flow){ vis[e[i].v]=1; d[e[i].v]=d[u]+1; q.push(e[i].v); } } } return vis[T]; } int dfs(int x,int a){ if(x==T || a==0) return a; int flow=0,f; for(int &i=cur[x];~i;i=e[i].next){ if(d[x]+1==d[e[i].v] && (f=dfs(e[i].v,min(a,e[i].cap-e[i].flow)))>0){ e[i].flow+=f; e[i^1].flow-=f; flow+=f; a-=f; if(a==0) break; } } return flow; } int solve(){ int ans=0; while(bfs()){ for(int i=0;i<=T;++i)cur[i]=first[i]; ans+=dfs(0,inf); } return ans; } int main(){ int n,m,i,j,k; while(scanf("%d%d",&n,&m)!=EOF){ LL s=0; memset(first,-1,sizeof(first)); tot=0; S=0,T=n*m+1; for(i=1;i<=n;++i){ for(j=1;j<=m;++j){ scanf("%d",&a[i][j]); s+=a[i][j]; int d1=(i-1)*m+j; if((i+j)%2==0){ add(S,d1,a[i][j]); for(k=0;k<4;++k){ int dx=i+fx[k][0]; int dy=j+fx[k][1]; if(dx>0&&dy>0&&dx<=n&&dy<=m){ int d2=(dx-1)*m+dy; add(d1,d2,inf); } } } else{ add(d1,T,a[i][j]); } } } cout<<s-solve()<<endl; } return 0; }
相关文章推荐
- hdu 1569 方格取数(2) 网络流--最大点权独立集
- HDU 1569 - 方格取数(2) 二分图最大点权独立集(构图最大流解)
- HDU 1565 && HDU 1569 方格取数 (网络流之最小割)
- hdu 1569 方格取数(2) (网络流)
- 【网络流第五弹】最大点权独立集 ——HDU 1569 方格取数(2)
- 【网络流】 HDU 1569 方格取数(2)
- 【网络流】 HDU 1569 方格取数(2)
- 二分图带权最大独立集 网络流解决 hdu 1569
- 独立最小【网络流第五弹】最大点权独立集 ——HDU 1569 方格取数(2)
- hdu 1569 方格取数2(网络流最小割)
- HDU 1569 方格取数(2) (二分图的最大点权独立集)
- Hdu 1569 方格取数(2) (网络流最大点权独立集)
- Round 6 F - 方格取数(2) HDU - 1569 网络流
- 方格取数(2) HDU - 1569(二分图最大点权独立集)
- 【HDU 1569 方格取数(2)】 网络流
- 【网络流】hdu 1569 方格取数(2)
- HDU 1569 方格取数(2) 网络流的应用
- 【网络流】 hdu 1569 方格取数(2)
- HDU1569 方格取数(2) 网络流
- 二分图带权最大独立集 网络流解决 hdu 1569