Hrbust oj 2163 棋盘取数(二分图+最大流)
来源:互联网 发布:知乎奇怪的问题 编辑:程序博客网 时间:2024/05/08 16:41
棋盘取数
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 66(22 users) Total Accepted: 18(11 users) Rating: Special Judge: No
Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。现在从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数x(n<=20, 0 <= x <= 1000)。
Output
对于每个测试实例,输出可能取得的最大的和。
Sample Input
3
258 83 905
874 941 662
733 415 890
Sample Output
3727
题解:这是个二分图,求的是最大点权独立集。最大点权独立集=总权值-最小点权覆盖。设下标和为偶数的点为X,下表和为奇数的点为Y。则ss连x,流量为mp[x],y连tt,流量为mp[y].x连周围4个点,流量为INF。
代码:
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<vector>#include<queue>#include<stack>#include<set>#include<algorithm>#include<map>#include<time.h>#include<math.h>//#define pb push_back//#define mp make_pair#define INF 0x3f3f3f3fusing namespace std;typedef long long int ll;typedef pair<int,int>pp;const int N=1e3+100;const int mod=1e9+7;int read(){ int x=0; char ch = getchar(); while('0'>ch||ch>'9')ch=getchar(); while('0'<=ch&&ch<='9') { x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); } return x;}/***********************************************************/int fx[4]= {0,0,1,-1};int fy[4]= {1,-1,0,0};int t,n,m,u,v,c,ss,tt;int cnt,sum;struct node{ int to,w,next;} edge[N<<2];int dep[N];int vis[N];int head[N<<2];int mp[50][50];void add(int f,int to,int w){ edge[cnt].to=to; edge[cnt].w=w; edge[cnt].next=head[f]; head[f]=cnt++;}int makedep(){ memset(dep,0,sizeof(dep)); queue<int>s; s.push(ss); dep[ss]=1; while(!s.empty()) { int u=s.front(); if(u==tt) return 1; s.pop(); for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].to; int w=edge[i].w; if(w&&dep[v]==0) { dep[v]=dep[u]+1; s.push(v); } } } return 0;}int dfs(int u,int maxflow,int tt){ if(u==tt) return maxflow; int ret=0; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].to; int w=edge[i].w; if(w&&dep[v]==dep[u]+1) { int f=dfs(v,min(maxflow-ret,w),tt); edge[i].w-=f; edge[i^1].w+=f; ret+=f; if(ret==maxflow) return ret; } } return ret;}void Dinic(){ int ans=0; while(makedep()==1) { ans+=dfs(ss,INF,tt); } printf("%d\n",sum-ans);}void solve(){ for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if((j+i)%2==0) { add(ss,(i-1)*n+j,mp[i][j]); add((i-1)*n+j,ss,0); } else { add((i-1)*n+j,tt,mp[i][j]); add(tt,(i-1)*n+j,0); } } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if((i+j)%2==1) continue; else { for(int k=0; k<4; k++) { int x=i+fx[k]; int y=j+fy[k]; if(x>=1&&x<=n&&y>=1&&y<=n) { add((i-1)*n+j,(x-1)*n+y,INF); add((x-1)*n+y,(i-1)*n+j,0); } } } } }}int main(){ while(~scanf("%d",&n)) { cnt=0; memset(head,-1,sizeof(head)); ss=n*n+1; tt=ss+1; sum=0; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%d",&mp[i][j]); sum+=mp[i][j]; } } solve(); Dinic(); } return 0;}
阅读全文
0 0
- Hrbust oj 2163 棋盘取数(二分图+最大流)
- hrbust 2163 棋盘取数【最大权独立集合-------最大流Dinic】
- 哈理工oj/hrbust 1492 盒子【最大二分匹配】
- hrbust 1492 盒子 二分图最大匹配
- HDU OJ 1281 棋盘游戏【二分图匹配之最大匹配重要点】
- hdu1565 方格取数 最大流(二分图极大点权独立集) 或状态压缩dp
- P1035 棋盘覆盖 (二分图匹配、最大网络流)
- hdu1281 棋盘游戏(枚举 + 二分图最大匹配)
- HDOJ 1281 棋盘游戏(二分图最大匹配)
- hdu 1281 棋盘游戏(枚举,二分图最大匹配)
- hdu 1281 棋盘游戏 (二分图最大匹配)
- 二分图最大匹配(HDU1281:棋盘游戏)
- 棋盘游戏 (二分图的最大匹配)
- HDU1281棋盘游戏 二分图最大匹配
- HDU 1569 - 方格取数(2) 二分图最大点权独立集(构图最大流解)
- hrbust 1798 秘密产奶机器 (最大流+二分答案)
- hrbust 1798 秘密产奶机器【二分+最大流】
- HLG 2163 方格取数 (最大网络流)
- 使用EKF算法处理IMU数据
- MySQL索引类型总结和使用技巧以及注意事项
- 性能调优第一篇-SQL格式化
- 字谜
- state
- Hrbust oj 2163 棋盘取数(二分图+最大流)
- 学生管理系统管理系统
- Linux Shell常用命令总结(51cto 博客搬迁)
- ping 网关不同的原因(51cto博客搬迁)
- Cisco Packet Tracer 使用方法(51cto博客搬迁)
- 博客搬迁
- 查看Windows端口占用情况
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
- netbeans 下 第三方库的导入问题