HDU 1498 50 years, 50 colors 二分图最小点覆盖

来源:互联网 发布:南京大汉网络做什么 编辑:程序博客网 时间:2024/05/28 09:32

题意:给一个n*n的矩阵,每个矩阵的格子里数字,代表格子里气球的颜色。每次可以消除同一行或者同一列里相同颜色的气球。问:哪种颜色的气球在m次之内不能被消除的?

思路:消除每种颜色的时候,行是X部,列是Y部,Aij是连通i行和j列的边。很明显是用点来覆盖边。就是求最小点覆盖。对于每种颜色都求一遍最小点覆盖就行了。

http://acm.hdu.edu.cn/showproblem.php?pid=1528

/*********************************************    Problem : HDU 1498    Author  : NMfloat    InkTime (c) NM . All Rights Reserved .********************************************/#include <map>#include <set>#include <queue>#include <stack>#include <cmath>#include <ctime>#include <cstdio>#include <vector>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#define rep(i,a,b)  for(int i = (a) ; i <= (b) ; i ++) //遍历#define rrep(i,a,b) for(int i = (b) ; i >= (a) ; i --) //反向遍历#define repS(it,p) for(auto it = p.begin() ; it != p.end() ; it ++) //遍历一个STL容器#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next) //遍历u所连接的点#define cls(a,x)   memset(a,x,sizeof(a))#define eps 1e-8using namespace std;const int MOD = 1e9+7;const int INF = 0x3f3f3f3f;const int MAXN = 1e5+5;const int MAXE = 2e5+5;typedef long long LL;typedef unsigned long long ULL;int T,n,m;int fx[] = {0,1,-1,0,0};int fy[] = {0,0,0,-1,1};struct Edge { //记录边    int to;    Edge * next;}E[MAXE],*EE;struct Gragh { //记录图的结点    Edge * first;}G[MAXN];int N,M;//二分图左右结点的个数bool visit[MAXN];int match[MAXN];//v2中匹配的情况void addedge(int u,int v) { //加边    EE->to = v ; EE -> next = G[u].first ; G[u].first = EE ++;    //EE->to = u ; EE -> next = G[v].first ; G[v].first = EE ++;}void init() {    EE = E; N = M = 0;    cls(G,0);}bool find_path(int u) {    int v;    repE(p,u) {        v = p->to;        if(!visit[v]) {            visit[v] = 1;            if(match[v] == -1 || find_path(match[v])) {//v没有匹配或者v可以找到另一条路径                match[v] = u;                return true;            }        }    }    return false;}int Max_match() {    cls(match,-1);    int cnt = 0;    rep(i,1,N) {        cls(visit,0);        if(find_path(i)) cnt ++;    }    return cnt;}int A[105][105];int ans[105];map<int,int>mp;void input() {    rep(i,1,n) rep(j,1,n) scanf("%d",&A[i][j]);}void solve() {    int cnt = 0;    mp.clear();    rep(i,1,n) rep(j,1,n) if(!mp[A[i][j]]) mp[A[i][j]] = 1;    repS(it,mp) {        int u = it->first;        init();        N = M = n;        rep(i,1,n) rep(j,1,n) {            if(A[i][j] == u) {                addedge(i,j+N);            }        }        if(Max_match() > m) { cnt ++ ; ans[cnt] = u;}    }     sort(ans+1,ans+cnt+1);    if(cnt == 0) {        puts("-1");    }    else {        rep(i,1,cnt-1) printf("%d ",ans[i]);        printf("%d\n",ans[cnt]);    }}int main(void) {    //freopen("a.in","r",stdin);    while(scanf("%d %d",&n,&m),n+m) {        input();        solve();    }    return 0;}
0 0
原创粉丝点击