1. 程式人生 > >1463 Strategic game 最小點覆蓋(二分圖匹配-匈牙利演算法)

1463 Strategic game 最小點覆蓋(二分圖匹配-匈牙利演算法)

最小點覆蓋問題 也是匹配問題

這裡用到了 匈牙利演算法,

還用到了結構體陣列存鄰接表的做法

**之前錯誤理解為最小邊覆蓋,6個點的鏈就卡到了邊覆蓋想法

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <ctype.h>
#include <vector>
#include <algorithm>
#include <sstream>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)

using namespace std;
typedef long long ll;
const int maxn = 1500+7, INF = 0x3f3f3f3f;
int n, cur, ans;
int f[maxn];
bool vis[maxn];
int next[maxn];

struct edge {
    int v, bef;
}e[maxn*2];

void add(int x, int y) {
    e[cur].v = y;
    e[cur].bef = next[x];
    next[x] = cur++;
}

void init() {
    memset(next, -1, sizeof(int)*(n+1));
    cur = 1;
    for(int j = 0; j < n; ++j) {
        int u, v, cnt;
        scanf("%d:(%d)", &u, &cnt);
        for(int i = 0; i < cnt; ++i) {
            scanf("%d", &v);
            add(u, v);
            add(v, u);
            //a[u].push_back(v);
            //a[v].push_back(u);
        }
    }
    memset(f, -1, sizeof(int)*(n+1));
}

bool dfs(int id) {
    for(int i = next[id]; i != -1; i = e[i].bef) {
        if(!vis[e[i].v]) {
            vis[e[i].v] = 1;
            if(f[e[i].v] == -1 || dfs(f[e[i].v])) {
                f[id] = e[i].v;
                f[e[i].v] = id;
                return true;
            }
        }
    }
    return false;
}

int main() {

    while(scanf("%d", &n) != EOF && n) {
        init();
        ans = 0;
        for(int i = 0; i < n; ++i) {
            if(f[i] == -1) {
                memset(vis, false, sizeof(bool)*(n+1));
                if(dfs(i)) ans++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}