HDU 1569 方格取数(2) dinic算法
2013-04-18 10:22
197 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1569
题意:
给出M*N的格子,每个格子里都有数字,问你怎么样取数字能使其和最大,前提是取出来的格子不能两两相邻。
坑爹:
如果按照方格取数的方法教上去会超时。
解法:
struct Edge //记录边
{
int from; //边的起点
int to; //边的终点
int cap; //边的容量
int next; //优化DFS和BFS的搜索,因为边有很多个,每次从0开始找的话会超时,所以用个cur数组来初始化。
};
用dinic算法,里面有两个部分比较重要,一个是BFS,另一个是DFS。
BFS:利用BFS来对图进行一个分层,如图所示。
View Code
题意:
给出M*N的格子,每个格子里都有数字,问你怎么样取数字能使其和最大,前提是取出来的格子不能两两相邻。
坑爹:
如果按照方格取数的方法教上去会超时。
解法:
struct Edge //记录边
{
int from; //边的起点
int to; //边的终点
int cap; //边的容量
int next; //优化DFS和BFS的搜索,因为边有很多个,每次从0开始找的话会超时,所以用个cur数组来初始化。
};
用dinic算法,里面有两个部分比较重要,一个是BFS,另一个是DFS。
BFS:利用BFS来对图进行一个分层,如图所示。
View Code
#include<iostream> #include<queue> using namespace std; const int maxn = 50+10; const int E_maxn = 50000 + 10; const int INF = 0x3fffffff; struct Edge { int from; int to; int cap; int next; }; struct Edge edge[E_maxn]; int deep[maxn*maxn]; int cur[maxn*maxn]; int k; int n; int m; int temp[4][2] = {-1,0, 1,0, 0,-1, 0,1}; int MIN(int a,int b) { return a > b ? b : a; } void addedge(int from,int to,int cap) { edge[k].from = from; edge[k].to = to; edge[k].cap = cap; edge[k].next = cur[from]; cur[from] = k; k++; edge[k].from = to; edge[k].to = from; edge[k].cap = 0; edge[k].next = cur[to]; cur[to] = k; k++; } int judge(int x,int y) { if(x>0 && x<=n && y>0 && y<=m) { return 1; } return 0; } bool BFS() { memset(deep,-1,sizeof(deep)); queue<int> Q; Q.push(0); deep[0] = 0; while(!Q.empty()) { int x = Q.front(); Q.pop(); int i; for(i=cur[x]; i!=-1; i=edge[i].next) { int e = edge[i].to; if(deep[e] == -1 && edge[i].cap > 0) { deep[e] = deep[x] + 1; Q.push(e); } } } return deep[n*m+1] != -1; } int DFS(int x,int a) { if(x == n*m+1) { return a; } int flow = 0; for(int i=cur[x]; i!=-1 && flow<a; i=edge[i].next) { int e = edge[i].to; if(deep[x] + 1 == deep[e] && edge[i].cap > 0) { int f = MIN(edge[i].cap,a-flow); f = DFS(e,f); flow += f; edge[i].cap -= f; edge[i^1].cap += f; } } if(!flow) { deep[x] = -2;//没有必要再往这个点走了 } return flow; } int Dinic() { int flow = 0; int F=0; while(BFS()) { while(F=DFS(0,INF)) { flow += F; } } return flow; } int main() { while(cin>>n>>m) { int i; int j; memset(cur,-1,sizeof(cur)); k=0; int sum = 0; int num; for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%d",&num); sum+=num; if((i+j) % 2 == 0) { addedge(0,(i-1)*m+j,num); for(int z = 0; z<4; z++) { int x = i+temp[z][0]; int y = j+temp[z][1]; if(judge(x,y)) { addedge((i-1)*m+j,(x-1)*m+y,INF); } } } else { addedge((i-1)*m+j,n*m+1,num); for(int z = 0; z<4; z++) { int x = i+temp[z][0]; int y = j+temp[z][1]; if(judge(x,y)) { addedge((x-1)*m+y,(i-1)*m+j,INF); } } } } } int ans = Dinic(); cout<<sum-ans<<endl; } return 0; }
相关文章推荐
- hdu(1569)方格取数(2)(dinic算法)
- 独立最小【网络流第五弹】最大点权独立集 ——HDU 1569 方格取数(2)
- hdu 1569 方格取数(2)【最大权独立集合-------最大流Edmond_Karp】
- 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
- HDU1569 方格取数(2) 网络流
- HDU-1569 方格取数(2) 最小割最大流
- HDU 1565 1569 方格取数(最大点权独立集)
- hdu 1569 方格取数(2) 最大点权独立集
- hdu1569-方格取数-二分图网络流
- HDU 1569 方格取数(2)(最大点权独立集)
- HDU 1569 - 方格取数(2) 二分图最大点权独立集(构图最大流解)
- HDU 1565 1569 方格取数(最大点权独立集)
- HDU_1569 方格取数(2) 最小割
- Round 6 F - 方格取数(2) HDU - 1569 网络流
- HDU 1569 方格取数(2) 最大点权独立集
- 方格取数(2) HDU - 1569(二分图最大点权独立集)
- HDU 1569 方格取数(2) (最小割)
- hdu - 1565 方格取数(1) && 1569 方格取数(2) (最大点权独立集)
- 【网络流】 HDU 1569 方格取数(2)
- HDU 1569 方格取数(2)