hdu acm 1565 方格取数(1)
来源:互联网 发布:黑莓passport删除软件 编辑:程序博客网 时间:2024/06/07 07:57
方格取数(1)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7386 Accepted Submission(s): 2806
Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
375 15 21 75 15 28 34 70 5
Sample Output
188
解题关键:黑白染色。(横纵坐标相加分成奇,偶两部分),构造超级源点,汇点。原点到奇数点的权值为该点上的值,奇数点到相邻点的权值为INF,偶数点到汇点的权值为该点的值。求最小割。
最小割=最大流。
ans=总数的和-最小割。
最小割=最大流。
ans=总数的和-最小割。
#include <iostream>#include<string.h>using namespace std;#include<queue>#define INF 0x7fffffff#define MS(a,b) memset(a,b,sizeof(a))int mat[505][505],n,s,t,dis[300000],f,head[500005];#define MAXN 3000#include<algorithm>struct node{ int to,next,w;}edge[500005];void add(int u,int v,int w){ edge[f].to=v; edge[f].next=head[u]; edge[f].w=w; head[u]=f++; edge[f].to=u; edge[f].w=0; edge[f].next=head[v]; head[v]=f++;}int bfs(){ int i,x,v; MS(dis,-1); dis[s]=0; queue<int>q; q.push(s); while(!q.empty()) { x=q.front(); q.pop(); for(i=head[x];i!=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].w&&dis[v]==-1) { dis[v]=dis[x]+1; if(v==t)return 1; q.push(v); } } } return 0;}int dfs(int s,int cur_flow){ int i,v,tmp,dt=cur_flow;//dt为当前剩余流量。 if(s==t)return cur_flow; for(i=head[s];i!=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].w&&dis[s]==dis[v]-1) { int flow=dfs(v,min(dt,edge[i].w));//一条增广路,能够增广的流量,只能是路上最小流量边的流量 edge[i].w-=flow;//减少前向弧流量 edge[i^1].w+=flow;//增加后向弧流量 dt-=flow;//找到一条路,存起来 } } return cur_flow-dt;//一共增广的流量}int dinic(){ int ans=0; while(bfs()) ans+=dfs(s,INF); return ans;}int main(){ int i,j,sum,k,i1,j1; while(cin>>n) { t=n*n+n+1; f=sum=0; s=1; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { cin>>mat[i][j]; sum=sum+mat[i][j]; } MS(head,-1); for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if((i+j)%2==1) { add(1,i*n+j,mat[i][j]); if(i+1<=n) add(i*n+j,(i+1)*n+j,INF); if(i-1>=1) add(i*n+j,(i-1)*n+j,INF); if(j+1<=n) add(i*n+j,i*n+j+1,INF); if(j-1>=1) add(i*n+j,i*n+j-1,INF); } else add(i*n+j,t,mat[i][j]); } cout<<sum-dinic()<<endl; } return 0;}
0 0
- hdu acm 1565 方格取数(1)
- HDU 1565 方格取数(1)
- hdu 1565 方格取数(1)
- HDU-1565-方格取数(1)
- hdu 1565 方格取数(1)
- HDU 1565 方格取数(1)
- hdu(1565)方格取数(1)
- hdu 1565 方格取数(1)
- hdu 1565 方格取数(1)
- hdu 1565 方格取数(1)
- HDU - 1565 方格取数(1) (DP)
- hdu 1565 方格取数(1)
- HDU 1565 方格取数(1)
- HDU 1565 方格取数(1)
- HDU 1565 方格取数(1)
- HDU - 1565 方格取数(1)
- HDU 1565 方格取数(1)
- HDU 1565 方格取数(1)
- Javascript之Function
- 线程
- Netty4.0学习笔记系列之一:Server与Client的通讯
- cocos2dx使用了第三方库照样移植android平台-解决iconv库的移植问题
- 第一个童年游戏“动物棋",开发及移植到android
- hdu acm 1565 方格取数(1)
- PHP一键比对更新MYSQL数据库的一些想法
- hdoj 1027 Ignatius and the Princess II 【全排列】【STL】
- HTML DOM
- Android的错误
- c#往SQL Server写Emoji表情
- 从Android运行时出发,打造我们的脱壳神器
- javascript机制致错
- Android 简易版天气预报app的现实(4)