21 1 2C1 D1D1 C11 2 4C1 D1C1 D1C1 D2D2 C1 Sample Output13題目大意:
給你n只貓和m條狗,編號分別為1-n和1-m,然后有一場演出由一只貓和一條狗組成,有k個觀眾,他們希望哪一個應該出演,不希望看到哪一個出演,具體見題目描述,問怎么安排演出才能滿足大多數的觀眾并輸出最多的滿足的觀眾數
題目思路:
剛開始看到時沒有啥思路,然后想想題目要求最多的觀眾,如果我們貓和狗為集合建立二分圖的話,最后得到的是貓和狗的最大匹配而不是最多滿足的觀眾數,所以我們換著方式,以觀眾為集合建立二分圖,然后我們考慮如何來建圖,首先每個觀眾有自己喜歡的和不喜歡的,如果兩個觀眾一個喜歡貓1一個不喜歡貓1或者是一個不喜歡狗1一個喜歡狗1,那么必然這兩個觀眾的觀點存在矛盾,他們兩個只能滿足一個,既然這樣,我們就很好想到讓有矛盾的觀眾連邊,這樣最后就轉換成求最大獨立集了!
AC代碼:
#include<cstring>#include<cstdio>const int maxn = 1005;bool vis[maxn],mp[maxn][maxn];int link[maxn];int n,m,k;bool dfs(int u){ for(int i=1;i<=k;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(){ int t;scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&k); memset(link,-1,sizeof(link)); memset(mp,false,sizeof(mp)); int num1[1005],num2[1005]; char s1[1005][10],s2[1005][10]; for(int j=1;j<=k;j++){ scanf("%s %s",s1[j],s2[j]); num1[j]=0,num2[j]=0; int i=1; while(s1[j][i])num1[j]=num1[j]*10+s1[j][i]-'0',i++; i=1; while(s2[j][i])num2[j]=num2[j]*10 +s2[j][i]-'0',i++; for(int l=1;l<j;l++){ if(num1[l]==num2[j]&&s1[l][0]==s2[j][0]||num2[l]==num1[j]&&s2[l][0]==s1[j][0]) mp[l][j]=mp[j][l]=true; } } int ans = 0; for(int i=1;i<=k;i++){ memset(vis,false,sizeof(vis)); if(dfs(i))ans++; } printf("%d/n",k-ans/2); } return 0;}
新聞熱點
疑難解答