zoukankan      html  css  js  c++  java
  • 骑士共存问题(二分图最大独立集)

    //http://www.cnblogs.com/IMGavin/
    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <bitset>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    #define gets(A) fgets(A, 1e8, stdin)
    const int INF = 0x3F3F3F3F, N =  50000, MOD = 1003, M = 1000000;
    
    int dir[8][2] = {{1, 2}, {1, -2},{-1, -2}, {-1, 2},  {2, 1}, {-2, 1},{-2, -1}, {2, -1}};
    
    
    bool mp[210][210];
    const double EPS = 1e-6;
    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 n, m;
    	while(cin >> n >> m){
    		memset(mp, 0, sizeof(mp));
    		for(int i = 0; i < m; i++){
    			int x, y;
    			cin >> x >> y;
    			mp[x][y] = 1;
    		}
    		init();
    		int st = 0, des = n *n + 1;
    		for(int i = 1; i <= n; i++){
    			for(int j = 1; j <= n; j++){
    				if(mp[i][j]){
    					continue;
    				}
    				if((i + j) % 2){
    					for(int k = 0; k < 8; k++){
    						int x = i + dir[k][0];
    						int y = j + dir[k][1];
    						if(x >= 1 && x <= n && y >= 1 && y <= n){
    							if(!mp[x][y]){
    								add((i - 1) * n + j, (x - 1) * n + y, INF);	
    							}
    							
    						}
    					}
    					add(st, (i - 1) * n + j, 1);
    				}else{
    					add((i - 1) * n + j, des, 1);
    				}
    			}
    		}
    		printf("%d
    ", n * n - m - dinic(st, des, des + 2));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    用.NET读取Flash格式文件信息
    通过ASP.NET页面重启服务器
    Webservice优点与缺点
    iClient 6R for Flex移动端开发的Q&A
    GIS十年路
    脚本调用命令行
    FME的简单介绍
    GIS从信息化到领域化(一)
    GIS从信息化到领域化(二)
    理性的看待地理信息共享交换平台建设
  • 原文地址:https://www.cnblogs.com/IMGavin/p/6412899.html
Copyright © 2011-2022 走看看