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
Sample Output
HINT
在樣例中,在進入寶塔前,將門的順序換爲4 1 2 3.然後前三層分別使用2 0 1三把鑰匙拿到前三層的寶物
只需要算出能開多少門就可以了,不用換順序啥的.
代碼如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int map[1100][1100];
int used[1100];
int end[1100];//end在zzuli oj 上使用沒問題,但在hdoj上就會編譯錯誤
int a,b,n,m,i,j;
int dfs(int x)
{
int i;
for(i=0;i<n;i++)
{
if(map[x][i]==1 && !used[i])
{
used[i]=1;
if(end[i]==-1||dfs(end[i]))
{
end[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(map,0,sizeof(map));
memset(end,-1,sizeof(end));
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
map[i][a]=1;
map[i][b]=1;
}
int sum=0;
for(i=1;i<=m;i++)
{
memset(used,0,sizeof(used));
if(dfs(i))
sum++;
}
printf("%d\n",sum);
}
}