• 方格取数问题(二分图点权最大独立集)


    //http://www.cnblogs.com/IMGavin/
    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <set>
    #include <algorithm>
    using namespace std;
    
    const int INF = 0x3F3F3F3F, N = 1000008, MOD = 1003, M = 1000000;
    
    const double EPS = 1e-6;
    
    int dir[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    
    int head[N], tot;
    
    struct node{
    	int u, v, cap, next;
    }edge[M];
    int cur[N], lev[N], s[N];
    
    void init(){
    	memset(head, -1, sizeof(head));
    	tot = 0;
    }
    
    void add(int u, int v, int cap){
    	edge[tot].u = u;
    	edge[tot].v = v;
    	edge[tot].cap = cap;
    	edge[tot].next = head[u];
    	head[u] = tot++;
    //反向弧
    	edge[tot].u = v;
    	edge[tot].v = u;
    	edge[tot].cap = 0;
    	edge[tot].next = head[v];
    	head[v] = tot++;
    }
    
    bool bfs(int st, int des){
    	memset(lev, -1, sizeof(lev));
    	lev[st] = 0;
    	queue<int> q;
    	q.push(st);
    	while(!q.empty()){
    		int u = q.front();
    		q.pop();
    		for(int i = head[u]; i != -1; i = edge[i].next){
    			int v = edge[i].v;
    			if(edge[i].cap && lev[v] == -1){
    				lev[v] = lev[u] + 1;
    				q.push(v);
    				if(v == des){
    					return true;
    				}
    			}
    		}
    	}
    	return false;
    }
    //源点,汇点,点的数量
    int dinic(int st, int des, int n){
    	int ans = 0;
    	while(bfs(st, des)){
    		memcpy(cur, head, sizeof(int) * (n + 1));
    		int u = st, top = 0;
    		while(true){
    			if(u == des){
    				int mini = INF, loc;
    				for(int i = 0; i < top; i++){
    					if(mini > edge[s[i]].cap){
    						mini = edge[s[i]].cap;
    						loc = i;
    					}
    				}
    				for(int i = 0; i < top; i++){
    					edge[s[i]].cap -= mini;
    					edge[s[i] ^ 1].cap += mini;
    				}
    				ans += mini;
    				top = loc;
    				u = edge[s[top]].u;
    			}
    			int &i = cur[u];//引用类型
    			for(; i != -1; i = edge[i].next){
    				int v = edge[i].v;
    				if(edge[i].cap && lev[v] == lev[u] + 1){
    					break;
    				}
    			}
    			if(i != -1){
    				s[top++] = i;
    				u = edge[i].v;
    			}else{
    				if(!top){
    					break;
    				}
    				lev[u] = -1;
    				u = edge[s[--top]].u;
    			}
    		}
    	}
    	return ans;
    }
    int main(){
    	int m, n;
    	while(cin >> m >> n){
    		init();
    		int st = m * n, des = m * n + 1;
    		int sum = 0;
    		for(int i = 0; i < m; i++){
    			for(int j = 0; j < n; j++){
    				int val;
    				scanf("%d", &val);
    				sum += val;
    				if(((i + j) & 1) == 0){
    					add(st, i * n + j, val);
    					for(int k = 0; k < 4; k++){
    						int x = i + dir[k][0], y = j + dir[k][1];
    						if(x >= 0 && y >= 0 && x < m && y < n){
    							add(i * n + j, x * n + y, INF);
    						}
    					}
    				}else{
    					add(i * n + j, des, val);
    				}
    			}
    		}
    		printf("%d
    ", sum - dinic(st, des, des + 1));
    
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    轻松掌握Ajax.net系列教程十二:使用TabContainer&TabPanel
    轻松掌握Ajax.net系列教程十五:使用AutoCompleteExtender
    一步一步学Linq to sql(二):DataContext与实体
    一步一步学Linq to sql(十):分层构架的例子
    轻松掌握Ajax.net系列教程十四:使用CalendarExtender
    一步一步学Linq to sql(八):继承与关系
    整理了一些tsql技巧
    一步一步学Linq to sql(三):增删改
    数据库连接字符串大全
    海量数据库的查询优化及分页算法方案
  • 原文地址:https://www.cnblogs.com/IMGavin/p/6385768.html
Copyright © 2020-2023  润新知