题目地址:HDU 1498
晕啊。。。三个人同时做的这个题,结果全都理解错意思了。。而且每个人理解错的地方还都不一样。。但是样例还都能过,。。。简直炫酷。。。
题意:n*n的矩阵放置不同的颜色(不同的数字代表不同的颜色),你有k次选择,每一次只能选择某一行或某一列,可以消除该行(列)的所有颜色,问有哪几种颜色,无论怎样经过k次选择后依然无法完全抹去。
这个题的思路就是分别求出每种颜色的最少操作次数。然后只要大于k次的就是不符合要求的。然后输出就行了。
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; int link[200], vis[200], cnt, head[200], n, m, mp[200][200]; struct node { int u, v, next; }edge[100000]; void add(int u, int v) { edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } int dfs(int u) { int i; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!vis[v]) { vis[v]=1; if(link[v]==-1||dfs(link[v])) { link[v]=u; return 1; } } } return 0; } int hungary() { int i, ans=0; memset(link,-1,sizeof(link)); for(i=0;i<n;i++) { memset(vis,0,sizeof(vis)); ans+=dfs(i); } //printf("%d\n",ans); return ans; } int main() { int k, i, j, h, s, _hash[200], Q[200]; while(scanf("%d%d",&n,&k)!=EOF&&n&&k) { for(i=0;i<n;i++) { for(j=0;j<n;j++) { scanf("%d",&mp[i][j]); } } int tot=0; for(h=1;h<=50;h++) { memset(head,-1,sizeof(head)); cnt=0; for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(mp[i][j]==h) { add(i,j); } } } int ans=hungary(); if(ans>k) { Q[tot++]=h; } } if(tot==0) printf("-1\n"); else { for(i=0;i<tot-1;i++) { printf("%d ",Q[i]); } printf("%d\n",Q[tot-1]); } } return 0; }
HDU 1498 50 years, 50 colors(二分最大匹配之最小点覆盖)
时间: 2024-10-12 20:52:25