ZOJ 1516 Uncle Tom's Inherited Land (二分图最大匹配)

来源:互联网 发布:同城国际旅行社 java 编辑:程序博客网 时间:2024/06/06 10:38

解题思路:将相邻的两个节点分到二部图的两个集合中,然后跑最大匹配算法。

AC代码:

/*    @Author: wchhlbt    @Date:   2017/8/2*/#include <bits/stdc++.h>#define Fori(x) for(int i=0;i<x;i++)#define Forj(x) for(int j=0;j<x;j++)#define maxn 100#define inf 0x3f3f3f3f#define ONES(x) __builtin_popcount(x)#define _  << "  " <<using namespace std;typedef long long ll ;const double eps =1e-8;const int mod = 1000000007;typedef pair<int, int> P;const double PI = acos(-1.0);int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};inline int read(){ int num;    scanf("%d",&num);   return num;}int a[105][105];vector<P> e1,e2;int n,m;//注意给nx,ny赋值int vis[maxn];//存储每个点是否被访问过int g[maxn][maxn];//邻接矩阵int cx[maxn];//cx[i]表示最终求得的最大匹配中与xi匹配的y顶点int cy[maxn];int nx,ny;//分别存储x集合和y集合中的顶点个数int x[maxn];int y[maxn];bool f[maxn];//表示其属于哪个集合int dfs(int u){    for(int v = 1; v<=ny; v++){//遍历Y集合        if(g[u][v] && !vis[v]){            vis[v] = 1;            if(cy[v]==-1 || dfs(cy[v])){               cx[u] = v;               cy[v] = u;               return 1;             }        }    }    return 0;}int MaxMatch(){    int res = 0;    memset(cx,-1,sizeof cx);    memset(cy,-1,sizeof cy);    for(int i = 1; i<=nx; i++){//遍历X集合        if(cx[i]==-1){            memset(vis,0,sizeof vis);            res += dfs(i);        }    }    return res;}void init(){    e1.clear();    e2.clear();    memset(a,0,sizeof a);    memset(g,0,sizeof g);    nx = ny = 0;}bool connect(int i, int j){    if(abs(e1[i].first - e2[j].first)==1 && abs(e1[i].second-e2[j].second)==0)        return true;    if(abs(e1[i].first - e2[j].first)==0 && abs(e1[i].second-e2[j].second)==1)        return true;    return false;}int main(){    while(~scanf("%d%d",&n,&m) && n+m){        init();// e a g        int k = read();        for(int i = 0; i<k; i++){            int x = read(); int y = read();            a[x][y] = 1;        }        int cnt1 = 0, cnt2 = 0;        for(int i = 1; i<=n; i++){            for(int j = 1; j<=m; j++){                if(a[i][j]) continue;                if((i+j)%2==0)                    e1.push_back(make_pair(i,j));                else                    e2.push_back(make_pair(i,j));            }        }        for(int i = 0; i<e1.size(); i++){            for(int j = 0; j<e2.size(); j++){                if(connect(i,j)){                    g[i+1][j+1] = 1;                }            }        }        nx = e1.size();        ny = e2.size();        int ans = MaxMatch();        cout << ans << endl;    }        return 0;}


阅读全文
0 0
原创粉丝点击