zzuli oj 1918(二分圖匹配)

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

13 40 10 10 11 2

Sample Output

3

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);
	}
}

發佈了181 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章