【 Codeforces Round #268 (Div. 1)】B.Two Set【dfs找增广路】

来源:互联网 发布:mac怎么下载穿越火线 编辑:程序博客网 时间:2024/06/05 10:53

其实题目就是要求每一个点都属于A或者B集合中,这相当于匹配问题,也就是尽可能让每一个点都匹配上,然后就是简单的找增广路的问题了。类似二分匹配。

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <map>using namespace std;#define N 200005map<int,int>M;vector<int>V[N][2];int n, tv[N], link[N], ca;int vis[N] = {0}, id[N];bool dfs(int u) {    int v, i, j, q;    for (i = 0;i < 2;i++) {        for (j = 0;j < V[u][i].size();j++) {            v = V[u][i][j];            if (vis[v] == ca) continue;            vis[v] = ca;            q = link[v];            link[v] = u;            if (q == -1 || dfs(q)) {                id[u] = id[v] = i;                return true;            }            link[v] = q;        }    }    return false;}bool work() {    memset(vis, 0, sizeof(vis));    memset(link, -1, sizeof(link));    int i;    for (i = 0;i < n;i++) {        ca = i+1;        if (!dfs(i)) return false;    }    return true;}int main() {    int a, b, i, j;    while (~scanf("%d%d%d", &n, &a, &b)) {        M.clear();        for (i = 0;i < n;i++) {            scanf("%d", &tv[i]);            M[tv[i]] = i;            V[i][0].clear(), V[i][1].clear();        }        for (i = 0;i < n;i++) {            int tm = a-tv[i];            if (tm == tv[i]) V[i][0].push_back(i+n);            else if (M.find(tm) != M.end()) {                V[i][0].push_back(M[tm]);            }            tm = b-tv[i];            if (tm == tv[i]) V[i][1].push_back(i+n);            else if (M.find(tm) != M.end()) {                V[i][1].push_back(M[tm]);            }        }        if (work()) {            puts("YES");            for (i = 0;i < n;i++) {                if (i) printf(" ");                printf("%d", id[i]);            }            puts("");        }else puts("NO");    }}


0 0
原创粉丝点击