大意: x,y表示信x不会再信封y中,那么有多少匹配能唯一匹配可能。
思路:就是判断匹配线是不是关键匹配。(类似关键点的判断)。只不过还需要一个cro[],来存储当前数组下标和那个点匹配的(下标为信,数值为信封的编号)。
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#define inf 0x3f3f3f3f
using namespace std;
int Map[600][600],cropath[600],cro[600];
bool use[600];
int n;
int DFS(int v)
{
int i;
for(i=1;i<=n;i++){
if(!use[i]&&!Map[v][i]){
use[i]=true;
if(cropath[i]==-1||DFS(cropath[i])){
cropath[i]=v;
cro[v] = i;
return 1;
}
}
}
return 0;
}
int main()
{
int i,j,k;
while(~scanf("%d",&n)){
for(i = 1;i <= n ;++ i){
for(j = 1;j <= n;++ j){
Map[i][j] = 0;
}
}
int a,b;
while(~scanf("%d%d",&a,&b)){
if(a==0&&b==0) break;
Map[a][b] = 1;
}
int ans = 0;
memset(cro,-1,sizeof(cro));
memset(cropath,-1,sizeof(cropath));
for(i = 1;i <= n;++ i){
memset(use,false,sizeof(use));
if(DFS(i)){
ans++;
}
}
// for(i = 1;i <= n;++ i){
// printf("%d %d\n",i,cropath[i]);
// }
if(ans!=n){
printf("none\n\n");continue;
}
int cnt = 0;
for(i = 1;i <= n;++ i){
int tmp = cro[i];
cropath[tmp] = -1;
Map[i][tmp] = 1;
memset(use,false,sizeof(use));
if(!DFS(i)){
cropath[tmp] = i;
cnt++;
printf("%d %d\n",i,cro[i]);
}
Map[i][tmp] = 0;
}
if(!cnt){
puts("none");
}
puts("");
}
return 0;
}