日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P2055 [ZJOI2009]假期的宿舍(二分图匹配)

發布時間:2024/9/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P2055 [ZJOI2009]假期的宿舍(二分图匹配) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述
學校放假了 · · · · · · 有些同學回家了,而有些同學則有以前的好朋友來探訪,那么住宿就是一個問題。

比如 A 和 B 都是學校的學生,A 要回家,而 C 來看B,C 與 A 不認識。我們假設每個人只能睡和自己直接認識的人的床。那么一個解決方案就是 B 睡 A 的床而 C 睡 B 的床。而實際情況可能非常復雜,有的人可能認識好多在校學生,在校學生之間也不一定都互相認識。

我們已知一共有 n 個人,并且知道其中每個人是不是本校學生,也知道每個本校學生是否回家。問是否存在一個方案使得所有不回家的本校學生和來看他們的其他人都有地方住。

輸入輸出格式
輸入格式:
第一行一個數 T 表示數據組數。接下來 T 組數據,每組數據第一行一個數n 表示涉及到的總人數。

接下來一行 n 個數,第 i 個數表示第 i 個人是否是在校學生 (0 表示不是,1 表示是)。再接下來一行 n 個數,第 i 個數表示第 i 個人是否回家 (0 表示不回家,1 表示回家,注意如果第 i 個人不是在校學生,那么這個位置上的數是一個隨機的數,你應該在讀入以后忽略它)。

接下來 n 行每行 n 個數,第 i 行第 j 個數表示 i 和 j 是否認識 (1 表示認識,0 表示不認識,第 i 行 i 個的值為 0,但是顯然自己還是可以睡自己的床),認識的關系是相互的。

輸出格式:
對于每組數據,如果存在一個方案則輸出 “^_^”(不含引號) 否則輸出“T_T”(不含引號)。(注意輸出的都是半角字符,即三個符號的 ASCII 碼分別為94,84,95)

輸入輸出樣例
輸入樣例#1:
1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
輸出樣例#1:

^_^

說明
對于 30% 的數據滿足 1 ≤ n ≤ 12。

對于 100% 的數據滿足 1 ≤ n ≤ 50,1 ≤ T ≤ 20。

多組數據!!!
/*
一開始沒有了解二分圖匹配,直接用DFS爆搜,然后只得了90分,有一組測試數據TEL
后來了解了一下二分圖匹配,把之前的代碼稍微改進了一下,就AC了
*/

//改進后100分code #include <iostream> #include <string.h> #include <vector> using namespace std; struct person {int stu;int goHome; }; vector<int>v1,v2[55]; bool used[55]; int flag,aim; int link[55]; int DFS(int x) {for(int i = 0; i < v2[x].size(); i++){int k = v2[x][i];if(!used[k])//防止匹配到這張床之后(DFS(link[k]))又回到這張床{used[k] = true;if(!link[k]||DFS(link[k]))//這張床沒有主人or這張床有主人了但那個主人可以去別的床{link[k] = x;//讓這張床的主人為當前來匹配的這個人return 1;}}}return 0; } int main() {int t,x;cin>>t;while(t--){int n;cin>>n;person data[n+5];int sum = 0;for(int i = 1; i <= n; i++){cin>>data[i].stu;if(data[i].stu)sum++;v2[i].clear();}v1.clear();for(int i = 1; i <= n; i++){cin>>data[i].goHome;if((data[i].stu&&!data[i].goHome)||!data[i].stu){v1.push_back(i);}}aim = v1.size();for(int i =1; i <= n; i++){for(int j = 1; j <= n ; j++){cin>>x;if(i==j||x){if(data[j].stu)v2[i].push_back(j);}}}flag = 0;memset(link,0,sizeof(link));if(aim <= sum){int cnt = 0;for(int i = 0; i < v1.size(); i++){memset(used,false,sizeof(used));cnt += DFS(v1[i]);}if(cnt == aim)//最大匹配達標flag = 1;}if(flag)cout<<"^_^"<<endl;elsecout<<"T_T"<<endl;}return 0; } //90分TELcode #include <iostream> #include <string.h> #include <vector> using namespace std; struct person {int stu;int goHome; }; vector<int>v1,v2[55]; bool used[55]; int a[55][55],flag,aim; void DFS(int now,int cnt) {if(aim-now > cnt)return;if(now == aim){flag = 1;return;}if(!flag){for(int i = 0; i < v2[v1[now]].size(); i++){int k = v2[v1[now]][i];if(!used[k]){used[k] = true;DFS(now+1,cnt-1);used[k] = false;}}return;} } int main() {int t;cin>>t;while(t--){int n;cin>>n;person data[n+5];int sum = 0;for(int i = 1; i <= n; i++){cin>>data[i].stu;if(data[i].stu)sum++;v2[i].clear();}v1.clear();for(int i = 1; i <= n; i++){cin>>data[i].goHome;if((data[i].stu&&!data[i].goHome)||!data[i].stu){v1.push_back(i);}}aim = v1.size();for(int i =1; i <= n; i++){for(int j = 1; j <= n ; j++){cin>>a[i][j];if(i==j||a[i][j]){if(data[j].stu)v2[i].push_back(j);}}}flag = 0;memset(used,false,sizeof(used));if(aim <= sum)DFS(0,sum);if(flag)cout<<"^_^"<<endl;elsecout<<"T_T"<<endl;}return 0; }

總結

以上是生活随笔為你收集整理的P2055 [ZJOI2009]假期的宿舍(二分图匹配)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。