zoukankan      html  css  js  c++  java
  • {POJ}{4000}{National Treasures}{二分匹配}

    思路:观察宝物周围的keypoints与宝物位置的距离是奇数,也就转化成为染色问题,将图进行染色,黑色与白色之间构成二分图,求最小边覆盖即可。一道经典的染色转化问题。

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <memory>
    #include <cmath>
    #include <bitset>
    #include <queue>
    #include <vector>
    #include <stack>
    using namespace std;
    
    const int MAXN = 2800;
    const int INF = (1<<30);
    
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))
    #define rep(i,x,y) for(i=x;i<y;++i)
    
    int dir[12][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},
    	{1,2},{2,1},{2,-1},{1,-2},
    	{-1,0},{0,1},{1,0},{0,-1}};
    int r,c,ind,ans;
    int g[MAXN][MAXN];
    int tt;
    typedef struct{
    	int v,next;
    }Edge;
    Edge edge[MAXN*MAXN];
    int net[MAXN];
    int pre[MAXN];
    bool vt[MAXN];
    
    bool _check(const int& x, const int& y )
    {
    	if( x < 0 || x >= r || y < 0 || y >= c)
    		return false;
    	return true;
    }
    void add_edge(const int& u , const int& v)
    {
    	edge[ind].v = v;
    	edge[ind].next = net[u];
    	net[u] = ind;
    	++ind;
    }
    bool dfs(const int& u)
    {
    	int i,v;
    	for( i = net[u]; i != -1; i = edge[i].next){
    		v = edge[i].v;
    		if( !vt[v] ){
    			vt[v] = true;
    			if( pre[v] == -1 || dfs(pre[v])){
    				pre[v] = u;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    void init()
    {
    	CLR(net,-1);
    	CLR(pre,-1);
    	CLR(vt,0);
    	ind = 0;
    	return ;
    }
    void make_graph()
    {
    	int i,j,tmp,u,v,x,y,k;
    	rep(i,0,r)
    		rep(j,0,c){
    			rep(k,0,13){
    				if( g[i][j] == -1 )
    					continue;
    				if(g[i][j] & (1<<k)){
    					x = i + dir[k][0];
    					y = j + dir[k][1];
    					if( !_check(x,y) )
    						continue;
    					if( g[x][y] == -1)
    						continue;
    					u = i*c + j;
    					v = x*c + y;
    					if( (i+j)&1 )
    						add_edge(v,u);
    					else
    						add_edge(u,v);
    				}
    			}
    		}
    	return ;
    }
    int work()
    {
    	int i,j,u,v,tmp;
    	rep(i,0,r)
    		rep(j,0,c)
    			scanf("%d",&g[i][j]);
    	make_graph();
    	int cnt = r*c;
    	ans = 0;
    	rep(i,0,cnt){
    		CLR(vt,0);
    		if( dfs(i) )
    			++ans;
    	}
    	printf("%d. %d\n",tt,ans);
    	return 0;
    }
    int main()
    {
    	tt = 0;
    	while(scanf("%d%d",&r,&c)){
    		++tt;
    		if( r==0 || c == 0)
    			break;
    		init();
    		work();
    	}
    	return 0;
    }
    
  • 相关阅读:
    PAT 甲级 1115 Counting Nodes in a BST (30 分)
    PAT 甲级 1114 Family Property (25 分)
    PAT 甲级 1114 Family Property (25 分)
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
  • 原文地址:https://www.cnblogs.com/lvpengms/p/2508854.html
Copyright © 2011-2022 走看看