【ACM】杭電OJ 2063
阿新 • • 發佈:2018-11-25
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=2063
借鑑:http://blog.sina.com.cn/s/blog_ac5ed4f30101ewjk.html
二分圖(二部圖):圖論中的一種特殊模型。設G(V,E)是一個無向圖,如果頂點V可以分割成為兩個互不相交的子集(A,B),並且圖中的每一條邊(i,j)所關聯的兩個頂點 i 和 j 分別屬於這兩個不同的頂點集(i in A ,j in B),則稱G是一個二分圖。
最大匹配:給定一個二分圖G,在G的一個子圖M種,M的邊集中任意兩條邊都不依附於同一頂點,則稱M是一個匹配。如果一個匹配中,圖中的每個頂點都和圖中某條邊相關聯,則稱此匹配為完全匹配,也稱作完備匹配。
增廣路(增廣軌或者交錯軌):若P是圖G中一條連通兩個未匹配頂點的路徑,並且屬M的邊和不屬M的邊(即已匹配和待匹配的邊)在P上交替出現,則稱P為相對於M的一條增廣路徑。(來源於二分圖【百度百科】)
交替路:從一個未匹配點出發,依次經過非匹配邊,匹配邊,非匹配邊,形成的路徑叫交替路。
增廣路:從一個未匹配點出發,走交替路,如果途徑另一個未匹配點(出發的點不算),則這條交替路稱為增廣路。(來源於:二分圖的最大匹配、完美匹配和匈牙利演算法【部落格園】)
初始化:
0對,無匹配
第一遍
1對, a--A
2對, a--B ,b--A
3對, a--B ,b--C ,c--A
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 505;
int map[maxn][maxn];
int vis[maxn];
int pri[maxn];
int K,M,N;
int find(int x)
{
int i;
for(i=1;i<=N;i++)
{
if(vis[i]==0 && map[x][i])
{
vis[i]=1;
if(pri[i]==-1 || find(pri[i]))
{
pri[i]=x;
return 1;
}
}
}
return 0;
}
int main ()
{
int k,j,i,sum;
while(scanf("%d",&K)!=EOF && K)
{
sum=0;
memset(map,0,sizeof(map));
memset(pri,-1,sizeof(pri));
scanf("%d%d",&M,&N);
for(k=1;k<=K;k++)
{
scanf("%d%d",&i,&j);
map[i][j]=1;
}
for(i=1;i<=M;i++)
{
memset(vis,0,sizeof(vis));
if(find(i))
sum++;
}
printf("%d\n",sum);
/*for(i=1;i<=N;i++)
{
printf("%d %d\n",pri[i],i);
}*/
}
return 0;
}
帶註釋的是輸出列印檢視所配對的種類