G
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 347 Solved: 80
SubmitStatusWeb Board
Description
晴天也來尋寶啦,有一個m層的寶塔,只能從第一層開始一層一層的往上走,每層都有一個門,你需要用鑰匙來打開門才能繼續走,現在晴天有n把鑰匙,編號爲0-n-1,然後他要開始尋寶了。沒有特殊技能怎麼好意思出來尋寶呢,他現在有兩個天賦技能,他知道第i層的門可以用編號爲a和b的鑰匙打開(可能a等於b呦),然後他還可以在進入寶塔前把門的順序任意調換一次,也就是說比如可以把m層原來的1 2 3 ..m,換爲 m …3 2 1.晴天想知道他最多能拿到多少層的寶物。
Input
第一行一個整數t表示有多少組測試實例
每組數據第一行爲兩個整數n,m分別表示有多少個鑰匙,有多少層。
接下來m行,每行兩個數字x,y,第i行表示第i層的門可以用標號x或y的鑰匙打開。
(n,m<=1000)
Output
輸出一個整數表示最多可以上多少層。
Sample Input
1
3 4
0 1
0 1
0 1
1 2
Sample Output
3
HINT
在樣例中,在進入寶塔前,將門的順序換爲4 1 2 3.然後前三層分別使用2 0 1三把鑰匙拿到前三層的寶物
Source
haut
很裸地二分圖
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
vector<int> G[1010];
int n;
int m;
int door[1111];
bool vis[1111];
bool DFS(int x){
for(int i=0;i<G[x].size();i++){
int v=G[x][i];
if(!vis[v]){
vis[v]=true;
if(door[v]==-1||DFS(door[v])){
door[v]=x;
return true;
}
}
}
return false;
}
int main(){
int T; int ans;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
memset(door,-1,sizeof(door));
for(int i=0;i<=1009;i++)
G[i].clear();
int a; int b;
for(int i=0;i<m;i++){
scanf("%d %d",&a,&b);
G[a].push_back(i);
G[b].push_back(i);
}
ans=0;
for(int i=0;i<n;i++){
memset(vis,false,sizeof(vis));
ans+=DFS(i);
}
printf("%d\n",ans);
}
return 0;
}