网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
2016-02-28 15:39
579 查看
HDU 1565 方格取数(1)
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)Output
对于每个测试实例,输出可能取得的最大的和Sample Input
3 75 15 21 75 15 28 34 70 5
Sample Output
188 直接用这个程序拿双倍经验吧~
#include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int INF=2147483647; const int maxn=10010,maxm=1000010; int cnt,fir[maxn],nxt[maxm],cap[maxm],to[maxm],dis[maxn],gap[maxn],path[maxn]; int map[53][53]; void addedge(int a,int b,int c) { nxt[++cnt]=fir[a]; to[cnt]=b; cap[cnt]=c; fir[a]=cnt; } bool BFS(int S,int T) { memset(dis,0,sizeof(dis)); dis[T]=1; queue<int>q;q.push(T); while(!q.empty()) { int node=q.front();q.pop(); for(int i=fir[node];i;i=nxt[i]) { if(dis[to[i]])continue; dis[to[i]]=dis[node]+1; q.push(to[i]); } } return dis[S]; } int fron[maxn]; int ISAP(int S,int T) { if(!BFS(S,T)) return 0; for(int i=1;i<=T;i++)++gap[dis[i]]; int p=S,ret=0; memcpy(fron,fir,sizeof(fir)); while(dis[S]<=T) { if(p==T){ int f=INF; while(p!=S){ f=min(f,cap[path[p]]); p=to[path[p]^1]; } p=T;ret+=f; while(p!=S){ cap[path[p]]-=f; cap[path[p]^1]+=f; p=to[path[p]^1]; } } int &ii=fron[p]; for(;ii;ii=nxt[ii]){ if(!cap[ii]||dis[to[ii]]+1!=dis[p]) continue; else break; } if(ii){ p=to[ii]; path[p]=ii; } else{ if(--gap[dis[p]]==0)break; int minn=T+1; for(int i=fir[p];i;i=nxt[i]) if(cap[i]) minn=min(minn,dis[to[i]]); gap[dis[p]=minn+1]++; fron[p]=fir[p]; if(p!=S) p=to[path[p]^1]; } } return ret; } void Init() { memset(fir,0,sizeof(fir)); memset(gap,0,sizeof(gap)); cnt=1; } int n,m; int dot(int x,int y){ return (x-1)*m+y; } int main() { int sum; while(~scanf("%d%d",&n,&m)) { Init();sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&map[i][j]); sum+=map[i][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if((i+j)%2==1){ addedge(0,(i-1)*m+j,map[i][j]); addedge((i-1)*m+j,0,0); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if((i+j)%2==0){ addedge((i-1)*m+j,n*m+1,map[i][j]); addedge(n*m+1,(i-1)*m+j,0); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if((i+j)%2==1){ if(i+1<=n){ addedge(dot(i,j),dot(i+1,j),INF); addedge(dot(i+1,j),dot(i,j),0); } if(i-1>=1){ addedge(dot(i,j),dot(i-1,j),INF); addedge(dot(i-1,j),dot(i,j),0); }if(j-1>=1){ addedge(dot(i,j),dot(i,j-1),INF); addedge(dot(i,j-1),dot(i,j),0); } if(j+1<=m){ addedge(dot(i,j),dot(i,j+1),INF); addedge(dot(i,j+1),dot(i,j),0); } } printf("%d\n",sum-ISAP(0,n*m+1)); } return 0; }
相关文章推荐
- TCP 三次握手理解和过程
- HTTP服务七层架构技术探讨
- 细说Http协议
- 细说Http协议
- 细说Http协议
- IOS Http断点续传浅析
- 文本分类算法之-LMS神经网络算法的介绍
- Linux网络配置 DNS配置重启失败
- 一文读懂卷积神经网络(转载)
- 有人串口转wifi模块 httpd client通信示例-用户使用网页通过服务器收发串口数据源码 小黄人软件
- 用keras小试CNN卷积神经网络应用于人脸识别
- 深入理解Java内存模型(二)——重排序http://www.infoq.com/cn/articles/java-memory-model-2
- 文本分类算法之--单层感知器的神经网络
- tcpdump&pt-query-digest分析mysql负载性能问题
- 从JVM并发看CPU内存指令重排序(Memory Reordering) http://ifeve.com/jvm-memory-reordering/
- Android开发之APN网络切换
- 文本挖掘分类算法--BP神经网络的一个具体的案例
- TCP/IP协议详解:卷一----笔记(2)数据链路层
- https 和 http区别
- TCP三次握手连接与四次握手断开