hdu1498

先贴一个好博客:好博客

hdu1498

以行为左点集, 列为右点集, 平面每个点mp[i,j]变成由行i和列j连接的边,题目变成了对每种颜色求这个二分图的最小点覆盖。

#include <iostream>
#include <cstring>
using namespace std;
int mp[105][105];
bool vis[105];
int x[105], y[105];
int n, k;
int find(int u, int color) {
   for(int v = 1; v <= n; v++) {
       if(mp[u][v] == color && !vis[v]) {
           vis[v] = true;
           if(x[v] == -1 || find(x[v], color)) {
               x[v] = u;
               return 1;
           }
       }
   }
   return 0;
}
int main() {
    while(cin >> n >> k) {
        if(!n) break;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) cin >> mp[i][j];
        }
        int ans[55], cnt = 0;
        for(int color = 1; color <= 50; color++) {
            int sum = 0;
            for(int i = 1; i <= n; i++) x[i] = -1;
           for(int i = 1; i <= n; i++) {
               memset(vis, 0, sizeof(vis));
               sum += find(i, color);
           }
           if(sum > k) ans[++cnt] = color;
        }
        if(!cnt) cout << -1 << '\n';
        else {
            for(int i = 1; i < cnt; i++) cout << ans[i] << " ";
            cout << ans[cnt] << '\n';
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/vege-chicken-rainstar/p/11253275.html
今日推荐