hdu 1569 方格取数(2) 网络流--最大点权独立集
2011-08-05 15:51
513 查看
hdoj 1569 网络流--最大点权独立集
上一个问题的升级版 数据加强了 不能再dp了
Total Submission(s): 1740 Accepted Submission(s): 507
[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]
[align=left]Sample Output[/align]
解:
按行数列数 i+j奇偶 划分为所有格子为两个集合
每个格子与周围格子连边 问题转化为求最大点权独立集
knig定理升级版吧 最大点权独立集=总数-最小点权覆盖=总数-最大流
证明可以参照百度百科 我都是在那看的
自己写的最大流代码 bfs() 搜增广路 速度可能有点慢...
可以换成isap算法
上一个问题的升级版 数据加强了 不能再dp了
方格取数(2)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1740 Accepted Submission(s): 507
[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
解:
按行数列数 i+j奇偶 划分为所有格子为两个集合
每个格子与周围格子连边 问题转化为求最大点权独立集
knig定理升级版吧 最大点权独立集=总数-最小点权覆盖=总数-最大流
证明可以参照百度百科 我都是在那看的
自己写的最大流代码 bfs() 搜增广路 速度可能有点慢...
可以换成isap算法
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<queue> using namespace std; #define MAXN 50 #define INF 1000000002 struct IM { int u,v,cap,flow; int link; }; IM edge[20000+10]; int matrix[MAXN+10][MAXN+10]; int head[MAXN*MAXN+10]; int dir[][2]={1,0,0,1,-1,0,0,-1}; int m,n,num; //行数 列数 bool Islegal(int x,int y) { if(x<=0||x>m||y<=0||y>n) return 0; return 1; } void edgeadd(int u,int v,int c) { edge[num].u=u; edge[num].v=v; edge[num].flow=0; edge[num].cap=c; edge[num].link=head[u]; head[u]=num++; edge[num].u=v; edge[num].v=u; edge[num].flow=0; edge[num].cap=0; edge[num].link=head[v]; head[v]=num++; } int Maxflow(int s,int t,IM *edge) { int i,j; int maxflow=0; int p[MAXN*MAXN+10]; int a[MAXN*MAXN+10]; queue<int> q; for(;;) { memset(a,0,sizeof(a)); a[s]=INF; q.push(s); while(!q.empty()) { i=q.front(); q.pop(); for(j=head[i];j!=-1;j=edge[j].link) { if(!a[edge[j].v] && edge[j].cap>edge[j].flow) { p[edge[j].v]=j; q.push(edge[j].v); a[edge[j].v]=a[i]<edge[j].cap-edge[j].flow?a[i]:edge[j].cap-edge[j].flow; } } } if(a[t]==0) break; for(i=t;i!=s;i=edge[p[i]].u) { edge[p[i]].flow+=a[t]; edge[p[i]^1].flow-=a[t]; } maxflow+=a[t]; } return maxflow; } int main() { int i,j,k; int total,s,t,sum; while(~scanf("%d%d",&m,&n)) { sum=0; total=m*n; s=0;t=total+1; for(i=1;i<=m;i++) for(j=1;j<=n;j++) { scanf("%d",*(matrix+i)+j); sum+=matrix[i][j]; } memset(head,-1,sizeof(head)); num=2; for(i=1;i<=m;i++) for(j=1;j<=n;j++) { if((i+j)%2) { edgeadd(s,(i-1)*n+j,matrix[i][j]); for(k=0;k<4;k++) { int x=i+dir[k][0]; int y=j+dir[k][1]; if(Islegal(x,y)) { edgeadd((i-1)*n+j,(x-1)*n+y,INF); } } } else edgeadd((i-1)*n+j,t,matrix[i][j]); } int ans=Maxflow(s,t,edge); printf("%d\n",sum-ans); } return 0; }
相关文章推荐
- 独立最小【网络流第五弹】最大点权独立集 ——HDU 1569 方格取数(2)
- hdu 1569 方格取数(2) 网络流 最大点权独立集
- 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
- 【网络流第五弹】最大点权独立集 ——HDU 1569 方格取数(2)
- hdu 1569 方格取数(2) 最大点权独立集
- 【HDU 1569】 方格取数2 --最大点权独立集
- hdu 1569 方格取数(2)【最大权独立集合-------最大流Edmond_Karp】
- HDU 1569 方格取数(2) 最大点权独立集
- hdu-1569(网络流)-最大点权独立集
- hdu 1569 方格取数(2) 最大点权独立集
- hdu 1569 方格取数——最大点权独立集
- hdu 1569 方格取数(2) 最大权独立集
- HDU 1569 方格取数(2) 最大点权独立集
- HDU 1569 方格取数(2)(最大独立点集)
- Hdu 1569 方格取数(2) (网络流最大点权独立集)
- HDU 1569 - 方格取数(2) 二分图最大点权独立集(构图最大流解)
- hdu 1565 方格取数(1) 最大点权独立集 网络流
- HDU 1565 方格取数(1) 二分图最大点权独立集
- 【网络流】hdu 1569 方格取数(2)
- hdu - 1565 方格取数(1) && 1569 方格取数(2) (最大点权独立集)