
1 112 11 11 22 11 22 25 41 2 3 4 52 3 4 5 13 4 5 1 24 5 1 2 35 1 2 3 43 350 50 5050 50 5050 50 500 0 Sample Output-1121 2 3 4 5-1 題目大意:給你一個n*n的矩陣,矩陣中每個格子對應一種顏色的氣球,問你踩n次,每次只能選擇一行或一列踩掉一種顏色的所有氣球,最后還剩余的氣球顏色有哪些
題目思路:
首先看下數據范圍,氣球顏色只有50種最多,矩陣大小100*100最大,所以我們可以枚舉每種顏色,對于每種顏色,我們進行行列匹配,x為一個集合,y為一個集合,最后匹配到的最大匹配數就是踩掉所有氣球所需的最小次數,這個應該不難想到,如果畫個圖來理解就是最小點覆蓋,而最小點覆蓋=最大匹配!
AC代碼:
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int maxn = 105;int n,k;int link[maxn],a[55],matrix[maxn][maxn];bool vis[maxn],mp[maxn][maxn];bool dfs(int u){ for(int i=1;i<=n;i++){ if(!vis[i]&&mp[u][i]){ vis[i]=true; if(link[i]==-1||dfs(link[i])){ link[i]=u; return true; } } } return false;}int main(){ while(scanf("%d%d",&n,&k),n+k){ memset(a,0,sizeof(a)); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&matrix[i][j]); a[matrix[i][j]]=1; } } int flag=1; for(int i=1;i<=50;i++){ if(!a[i])continue; //枚舉每種顏色,a[i]記錄該種顏色有沒有出現過 memset(mp,false,sizeof(mp)); memset(link,-1,sizeof(link)); int num = 0; for(int j=1;j<=n;j++) for(int l=1;l<=n;l++) if(matrix[j][l]==i)mp[j][l]=true; for(int j=1;j<=n;j++){ memset(vis,false,sizeof(vis)); if(dfs(j))num++; } if(num>k){ if(flag){printf("%d",i);flag=0;} else printf(" %d",i); } } if(flag)printf("-1"); printf("/n"); } return 0;}
新聞熱點
疑難解答