HDU 1569 方格取数(2) (二分图的最大点权独立集)
来源:互联网 发布:禁毒知识网络竞赛 分数 编辑:程序博客网 时间:2024/05/18 08:22
方格取数(2)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6704 Accepted Submission(s): 2152
Problem Description
给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3 375 15 21 75 15 28 34 70 5
Sample Output
188
Author
ailyanlu
Source
Happy 2007
POINT:
首先要明确的这是一张二分图。
(i+j)%2, 等于0就和s连,等于1就就t连。 另外从左点连到右点的边都是左点的上下左右,值inf。即(i+j)%2==0的上下左右。
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#include <vector>using namespace std;#define LL long longconst int maxn = 2600;const int inf = 0x3f3f3f3f;int n,m,t,s;int dir[4][2]={0,1,0,-1,-1,0,1,0};struct node{ int from,to,flow,cap; node(int u,int v,int f,int c): from(u),to(v),flow(f),cap(c){}};vector<int>edge[maxn];vector<node>len;void add(int u,int v,int cap){ len.push_back(node(u,v,0,cap)); len.push_back(node(v,u,0,0)); int now=len.size(); edge[u].push_back(now-2); edge[v].push_back(now-1);}int cur[maxn];int d[maxn],vis[maxn];bool bfs(){ queue<int>q; memset(vis,0,sizeof vis); memset(d,0,sizeof d); q.push(0); d[0]=1; vis[0]=1; while(!q.empty()) { int u=q.front();q.pop(); for(int i=0;i<edge[u].size();i++) { node e=len[edge[u][i]]; if(!vis[e.to]&&e.cap>e.flow) { d[e.to]=d[u]+1; vis[e.to]=1; q.push(e.to); } } } return vis[t];}int dfs(int u,int a){ if(u==t||a==0) return a; int flow=0,f; for(int &i = cur[u];i<edge[u].size();i++) { node &e = len[edge[u][i]]; if(d[u]==d[e.to]-1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0) { flow+=f; e.flow+=f; len[edge[u][i]^1].flow-=f; a-=f; } if(a==0) break; } if(flow==0) d[u]=-1; return flow;}int maxflow(){ int ans=0; while(bfs()) { memset(cur,0,sizeof cur); ans+=dfs(s,inf); } return ans;}void init(){ for(int i=0;i<maxn;i++) edge[i].clear(); len.clear();}int main(){ while(~scanf("%d %d",&n,&m)) { init(); int mp[55][55]; int cnt[55][55]; memset(cnt,0,sizeof cnt); int p=0; int sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&mp[i][j]); sum+=mp[i][j]; cnt[i][j]=++p; } s=0; t=n*m+1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if((i+j)%2==0) { add(s,cnt[i][j],mp[i][j]); } else add(cnt[i][j],t,mp[i][j]); if((i+j)%2==0) for(int k=0;k<4;k++) { int x=i+dir[k][1]; int y=j+dir[k][0]; if(x<1||x>n||y<1||y>m) continue; add(cnt[i][j],cnt[x][y],inf); } } } printf("%d\n",sum-maxflow()); }}
阅读全文
0 0
- HDU 1569 方格取数(2) (二分图的最大点权独立集)
- HDU 1569 - 方格取数(2) 二分图最大点权独立集(构图最大流解)
- HDU 1565 方格取数(1) 二分图最大点权独立集
- ★ 方格取数3 二分图的最大点权独立集
- hdu 1569 方格取数(2)--最大点权独立集-->最大流
- hdu1569 方格取数(2) 二分图最大点权独立集
- hdu 1569 方格取数 点最大独立集
- hdu 1569 方格取数(2) 网络流--最大点权独立集
- HDU 1569 方格取数(2)(最大点权独立集)
- Hdu 1569 方格取数(2) (网络流最大点权独立集)
- hdu 1569 方格取数(2) 最大点权独立集
- 【HDU 1569】 方格取数2 --最大点权独立集
- HDU 1569 方格取数(2) 最大点权独立集
- hdu 1569 方格取数(2) 网络流 最大点权独立集
- HDU 1569 方格取数(2)(最大点权独立集)
- HDU 1569 方格取数(2) 最大点权独立集
- nefu 482 方格取数问题 二分图最大点权独立集
- hdu 1569 方格取数 最大点权独立集(hdu 1565)
- iOS-去掉定位地址中不准确的楼层信息
- 02:计算(a+b)*c的值
- 第121届中国进出口商品交易会(广交会)-第一期会刊(参展商名录)
- 推荐系统老司机的十条经验节选
- 你应该使用Django admin的9个理由
- HDU 1569 方格取数(2) (二分图的最大点权独立集)
- 使用Mybatis Generator时遇到“Exception getting JDBC Driver”?
- eclipse代码格式化快捷键
- JavaScript高级程序设计(二)
- 微信小程序开发《二》:http请求的session管理
- 如何在PDF文件中插入一个空白页面
- 图解HTTP读书笔记(三 HTTP报文内的HTTP信息)
- No binary rubies available for: osx/10.8/x86_64/ruby-1.9.2-p320解决
- Mac下安装及配置redis-4.0.1