獨立集是指兩兩之間沒有邊的頂點集合。頂點數目最多的集合稱為最大獨立集。
二分圖最大獨立集 = 頂點數 - 二分圖最大匹配。
所以這題在於解決二個問題:
1、求二分圖的最大匹配。
由於左右兩個集合是同一集合,不分男女。所以,理論上講存在0到3,就一定存在3到0。剛開始的想法是只將0到3記起來,
3到0就不記錄了。這樣在求最大匹配是可以少點計算。可是卻WA了!不解。我還是覺得這種思路沒錯,並且可以減少時間。
個人懷疑是資料的問題了。
2、輸入的每組資料可以看成是一個字串。然後在處理之。當然,這題不看成字串也是可以的。因為數組資料的“:”、
“()”的位置是固定的,那麼就可以一個一個數來輸入了。
AC代碼:2871MS
#include<iostream>using namespace std;const int MAX=500; //最多人數const int help[]={1,10,100,1000,10000}; //輔助計算的數組bool map[MAX][MAX];bool used[MAX];int link[MAX];int n;char *tmp;void deal(char *a) //處理輸入的字串,不是0到9的字元全賦為'\0'{int i,len=strlen(a);for(i=0;i<len;i++){if(!(a[i]>='0' && a[i]<='9')){a[i]='\0';}}}int calculate(char *a) //計算字串的值,該字串全由數字組成{int len=strlen(a);int num=0;for(int i=len-1;i>=0;i--){num+=help[len-i-1]*(a[i]-'0');}return num;}void storeMap() //儲存二分圖{int i,j,k,row,col;char ch[MAX*2];memset(map,false,sizeof(map));getchar();for(i=1;i<=n;i++){gets(ch); //擷取整行,帶空格deal(ch);tmp=ch;row=calculate(tmp); //計算二分圖的左頂點while(*tmp!='\0')tmp++;while(*tmp=='\0')tmp++;k=calculate(tmp); //計算左頂點關聯的右頂點數while(*tmp!='\0')tmp++;for(j=0;j<k;j++){while(*tmp=='\0')tmp++;col=calculate(tmp); //二分圖右頂點while(*tmp!='\0')tmp++;//if(!map[col][row]) map[row][col]=true; //true表示左右頂點關聯}}}bool can(int t) //確定是否存在增廣路徑{for(int i=0;i<n;i++){if(!used[i] && map[t][i]){used[i]=true;if(link[i]==-1 || can(link[i])){link[i]=t;return true;}}}return false;}int maxMatch(){int num=0;memset(link,0xff,sizeof(link));for(int i=0;i<n;i++) //從每一左頂點出發尋找增廣路徑{memset(used,false,sizeof(used));if(can(i)) num++;}return num;}int main(){while(cin>>n){storeMap();cout<<n-maxMatch()/2<<endl;}return 0;}