• cf Two Sets (我用二分最大匹配做的)


    题意:

    n个数p1,p2....pn     两个数a,b

    把它们分成A,B两个集合。

    若x属于A,a-x一定属于A。

    若x属于B,b-x一定属于B。

    问是否可能将这n个数分成两个集合。若可以,输出每个数是属于A集合还是B集合(0:集合A,1:集合B)


    思路:

    这题我用二分图最大匹配做的。他们用并查集,额.. 一开始就没想过并查集哩,回头再看看并查集的思路吧。

    若x属于A,则a-x属于A。若a-x属于A,则x属于A。集合B同理。

    两两配对,若x和y可以装进一个集合,则将它们之间连条线。然后二分图最大匹配看匹配数是否等于n。

    开始时用map记录p[i]这个数在数组中的位置

    剩下看代码啦,易懂


    代码:

    #include <cstdio>
    #include <iostream>
    #include <string.h>
    #include <cstdlib>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <cmath>
    #include <map>
    #include <stack>
    using namespace std;
    int const uu[4] = {1,-1,0,0};
    int const vv[4] = {0,0,1,-1};
    typedef long long ll;
    int const maxn = 50005;
    int const inf = 0x3f3f3f3f;
    ll const INF = 0x7fffffffffffffffll;
    double eps = 1e-10;
    double pi = acos(-1.0);
    #define rep(i,s,n) for(int i=(s);i<=(n);++i)
    #define rep2(i,s,n) for(int i=(s);i>=(n);--i)
    #define mem(v,n) memset(v,(n),sizeof(v))
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    
    int n,a,b;
    int p[100005];
    vector<int> graph[100005];
    bool bmask[100005];
    int cx[100005], cy[100005];
    
    
    int findPath(int u){
        int L = graph[u].size();
        rep(i,0,L-1) if(!bmask[graph[u][i]]){
            bmask[graph[u][i]] = true;
            if(cy[graph[u][i]]==-1 || findPath(cy[graph[u][i]])){
                cy[graph[u][i]] = u;
                cx[u] = graph[u][i];
                return 1;
            }
        }
        return 0;
    }
    int MaxMatch(){
        int ans = 0;
        rep(i,1,n) cx[i] = cy[i ] = -1;
        rep(i,1,n) if(cx[i]==-1){
            mem(bmask,false);
            ans += findPath(i);
        }
        return ans;
    }
    
    int main(){
        map<int,int> mp;
    
        scanf("%d%d%d",&n,&a,&b);
        rep(i,1,n){
            scanf("%d",&p[i]);
            mp[p[i]] = i;
        }
        rep(i,1,n){
            if(mp[a-p[i]])
                graph[i].push_back(mp[a-p[i]]);
            if(mp[b-p[i]])
                graph[i].push_back(mp[b-p[i]]);
        }
        int dd = MaxMatch();
        if(dd!=n) printf("NO
    ");
        else{
            printf("YES
    ");
            rep(i,1,n){
                if(p[i]+p[cx[i]]==a) printf("0 ");
                else printf("1 ");
            }
            printf("
    ");
        }
    }

      



  • 相关阅读:
    《构建之法》阅读报告
    教务管理系统类图及数据库E/R图
    设计模式:抽象工厂
    结对项目:四则运算程序测试
    Leetcode笔记之57和为s的连续正数序列
    Leetcode笔记之1103分糖果 II
    Leetcode笔记之199二叉树的右视图
    每日Scrum(9)
    每日Scrum(7)
    每日Scrum(6)
  • 原文地址:https://www.cnblogs.com/fish7/p/3985282.html
Copyright © 2020-2023  润新知