Necklace (全排列 + 匈牙利)

#include<bits/stdc++.h>
using namespace std;

bool noway[20][20], Gra[20][20];
int arr[20];

int linker[20];
bool used[20];
bool dfs(int u, int vN) {
    for(int v = 1; v <= vN; v++)
        if(Gra[u][v] && !used[v]) {
            used[v] = true;
            if(linker[v] == -1 || dfs(linker[v], vN)) {
                linker[v] = u;
                return true;
            }
        }
    return false;
}
int hungary(int vN) {
    int res = 0;
    memset(linker,-1,sizeof(linker));
    for(int u = 1; u <= vN; u++) {
        memset(used,false,sizeof(used));
        if(dfs(u, vN))
            res++;
    }
    return vN - res;
}

int solve(int n) {
    memset(Gra, true, sizeof(Gra));
    for(int i = 2; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            if(noway[arr[i - 1]][j] || noway[arr[i]][j])
                Gra[i][j] = false;
    for(int i = 1; i <= n; i ++)
        if(noway[arr[1]][i] || noway[arr[n]][i])
            Gra[1][i] = false;
    return hungary(n);
}

int main() {
    int n,m,a,b;
    while(~scanf("%d%d",&n,&m)) {
        if(n == 0){
            printf("0\n");
            continue;
        }
        memset(noway, false, sizeof(noway));
        for(int i = 0; i < m; i ++) {
            scanf("%d%d",&a,&b);
            noway[b][a] = true;
        }
        int ans = 10000;
        for(int i = 1; i <= n; i ++) arr[i] = i;
        do {
            ans = min(solve(n), ans);
        } while(next_permutation(arr + 2, arr + n + 1));
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wethura/p/9727294.html
今日推荐