二分图的变种,行可以和多列匹配,条件是有白格,但列只有一个匹配行,要求每列都有且仅有一行匹配,且每行都有匹配的列。。。。若没有匹配的列就输出“NO”
按照二分匹配求出link[],若匹配数<n那么就是说,那就是说明有些行不能匹配 ;
然后在把未匹配好的列与行匹配 就ok了。
代码:
#include<stdio.h>
#include<string.h>
const int N = 1010 ;
int map[N][N] , used[N] , link[N] , n , m ;
bool find(int x)
{
for(int i=1;i<=m;i++)
{
if(!used[i]&&map[x][i])
{
used[i] = 1 ;
if(link[i]==-1||find(link[i]))
{
link[i] = x ;
return true ;
}
}
}
return false;
}
int main()
{
int T ;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m) ;
memset(map,0,sizeof(map));
int a , b ;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b) ;
map[a][i] = map[b][i] = 1 ;
}
memset(link,-1,sizeof(link));
int flag = 0 , sign = 0 ;
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(find(i)) flag ++ ;
}
if(flag<n)
{
printf("NO/n");
continue ;
}
for(int i=1;i<=m;i++)
{
if(link[i]==-1)
{
for(int j=1;j<=n;j++)
if(map[j][i]) link[i] = j ;
}
}
printf("%d",link[1]);
for(int i=2;i<=m;i++)
printf(" %d",link[i]);
printf("/n");
}
return 0 ;
}