现在的位置: 首页 > 综合 > 正文

POJ1469 COURSES

2018年12月18日 ⁄ 综合 ⁄ 共 1900字 ⁄ 字号 评论关闭

http://poj.org/problem?id=1469

求最大匹配。

code1:(匈牙利算法,寻找增广路的思想。

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

const int MAXN = 300 + 5;
vector<int> g[MAXN];
int from[MAXN], tot;
bool use[MAXN];
int n;

bool match(int x)
{
    for(int i = 0; i < g[x].size(); ++i)
        if(!use[g[x][i]]) {
            use[g[x][i]] = true;
            if(from[g[x][i]] == -1 || match(from[g[x][i]])) {
                from[g[x][i]] = x;
                return true;
            }
        }
    return false;
}

int hungary()
{
    tot = 0;
    memset(from, -1, sizeof from );
    for(int i=1; i<=n; ++i) {
        memset(use, 0, sizeof use);
        if(match(i))
            ++tot;
    }
    return tot;
}

void init()
{
    int i, k, m, x;
    scanf("%d%d",&n,&m);
    for(i=1; i<=n; ++i) {
        scanf("%d",&k);
        g[i].clear();
        while(k--) {
            scanf("%d",&x);
            g[i].push_back(x);
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--) {
        init();
        if(n == hungary()) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

code2:(Hopcroft-Karp算法)

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

const int maxn = 300 + 5;
int n1, n2;
vector<int> g[maxn];
int mx[maxn], my[maxn];
queue<int> que;
int dx[maxn], dy[maxn];
bool vis[maxn];

bool find(int u)
{
    for(int i=0; i<g[u].size(); ++i)
        if(!vis[g[u][i]] && dy[g[u][i]] == dx[u] + 1) {
            vis[g[u][i]] = true;
            if(!my[g[u][i]] || find(my[g[u][i]])) {
                mx[u] = g[u][i];
                my[g[u][i]] = u;
                return true;
            }
        }
    return false;
}

int matching()
{
    memset(mx, 0, sizeof mx );
    memset(my, 0, sizeof my );
    int ans = 0;
    while(true) {
        bool flag = false;
        while(!que.empty()) que.pop();
        memset(dx, 0, sizeof dx );
        memset(dy, 0, sizeof dy );
        for(int i=1; i<=n1; ++i)
            if(!mx[i]) que.push(i);
        while(!que.empty()) {
            int u = que.front();
            que.pop();
            for(int i= 0; i<g[u].size(); ++i)
                if(!dy[g[u][i]]) {
                    dy[g[u][i]] = dx[u] + 1;
                    if(my[g[u][i]]) {
                        dx[my[g[u][i]]] = dy[g[u][i]] + 1;
                        que.push(my[g[u][i]]);
                    } else
                        flag = true;
                }
        }
        if(!flag) break;
        memset(vis, 0, sizeof vis );
        for(int i=1; i<=n1; ++i)
            if(!mx[i] && find(i)) ans++;
    }
    return ans;
}

void init()
{
    int i, k, m, x;
    scanf("%d%d",&n1,&m);
    for(i=1; i<=n1; ++i) {
        scanf("%d",&k);
        g[i].clear();
        while(k--) {
            scanf("%d",&x);
            g[i].push_back(x);
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--) {
        init();
        if(n1 == matching()) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

抱歉!评论已关闭.