UVALive 5874 - Social Holidaying(一般图匹配带花树)

来源:互联网 发布:java怎么搭建服务器 编辑:程序博客网 时间:2024/04/29 14:06

题目:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93936#problem/E

题意:

给出n个家庭的人数,m个房子的容纳人数,两个家庭的总人数等于房子的容纳人数,则可以入住,求出可以入住的最多的家庭对。

思路:

一般图求最大匹配不可以用 二分图,要用 一般图匹配带花树。

具体解释:http://wenku.baidu.com/link?url=vVjAPB9qlmm4lh9x0asBo01D2MqPMocfZDrDdS66c6rBWL6MF5bYtpraU5a5rc9ms9pu66qBI4IFInUHwKBN_USirftHdNfKmWnOlDGCXsm

。。。(这道题的数据水了。。。

AC.

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <set>using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 405;int N;bool graph[maxn][maxn], Inqueue[maxn], Inpath[maxn], Inblossom[maxn];int Match[maxn];int Head, Tail;int Queue[maxn];int  Start, Finish;int Newbase;int Father[maxn], Base[maxn];int Count;void Push(int u){    Queue[Tail] = u;    Tail++;    Inqueue[u] = 1;}int Pop(){    int res = Queue[Head];    Head++;    return res;}int FindComAnc(int u, int v){    memset(Inpath, 0, sizeof(Inpath));    while(1) {        u = Base[u];        Inpath[u] = 1;        if(u == Start) break;        u = Father[Match[u]];    }    while(1) {        v = Base[v];        if(Inpath[v]) break;        v = Father[Match[v]];    }    return v;}void ResetTrae(int u){    int v;    while(Base[u] != Newbase) {        v = Match[u];        Inblossom[Base[u]] = Inblossom[Base[v]] = 1;        u = Father[v];        if(Base[u] != Newbase) Father[u] = v;    }}void BloosomContract(int u, int v){    Newbase = FindComAnc(u, v);    memset(Inblossom, 0, sizeof(Inblossom));    ResetTrae(u);    ResetTrae(v);    if(Base[u] != Newbase) Father[u] = v;    if(Base[v] != Newbase) Father[v] = u;    for(int tu = 1; tu <= N; ++tu) {        if(Inblossom[Base[tu]]) {            Base[tu] = Newbase;            if(!Inqueue[tu]) Push(tu);        }    }}void FindAugmentingPath(){    memset(Inqueue, 0, sizeof(Inqueue));    memset(Father, 0, sizeof(Father));    for(int i = 1; i <= N; ++i) {        Base[i] = i;    }    Head = Tail = 1;    Push(Start);    Finish = 0;    while(Head < Tail) {        int u = Pop();        for(int v = 1; v <= N; ++v) {            if(graph[u][v] && (Base[u] != Base[v]) && (Match[u] != v)) {                if((v == Start) || (Match[v] > 0) && Father[Match[v]] > 0) {                    BloosomContract(u, v);                }                else if(Father[v] == 0) {                    Father[v] = u;                    if(Match[v] > 0)                        Push(Match[v]);                    else {                        Finish = v;                        return;                    }                }            }        }    }}void AugmentPath(){    int u, v, w;    u = Finish;    while(u > 0) {        v = Father[u];        w = Match[v];        Match[v] = u;        Match[u] = v;        u = w;    }}void Edmonds(){    memset(Match, 0, sizeof(Match));    for(int u = 1; u <= N; ++u) {        if(Match[u] == 0) {            Start = u;            FindAugmentingPath();            if(Finish > 0) AugmentPath();        }    }}void PrintMatch(){    Count = 0;    for(int u = 1; u <= N; ++u) {        if(Match[u] > 0) Count++;    }    printf("%d\n", Count/2);}int val[maxn];set<int> s;int main(){    //freopen("in", "r", stdin);    int T;    scanf("%d", &T);    while(T--) {        s.clear();        memset(graph, 0, sizeof(graph));        int m;        scanf("%d%d", &N, &m);        for(int i = 1; i <= N; ++i) {            scanf("%d", &val[i]);        }        for(int i = 1; i <= m; ++i) {            int h;            scanf("%d", &h);            s.insert(h);        }        for(int i = 1; i <= N; ++i) {            for(int j = i+1; j <= N; ++j) {                if(s.find(val[i] + val[j]) != s.end()) {                    graph[i][j] = graph[j][i] = 1;                }            }        }        Edmonds();        PrintMatch();    }    return 0;}



0 0
原创粉丝点击