我们可以这样考虑这个,首先题目饶了一个弯,那就是给的是不能匹配的,于是我们可以思考,如果我们直接匹配的话,如果不存在完美匹配,那说明了这个必然无解。
但是我们可以发现完美匹配的方案有很多,所以我们必须要想一个办法确定当前是否存在唯一解。
于是我们继续思考,假如这封信存在唯一解,那说明假如没有这个解,那么必然无解,如果有多组解,那必然仍然存在完美匹配。
所以我们枚举最开始判断出来的那组解在破坏情况下是否存在完美匹配即可
tips:不过为什么我codevAC了但是福州大学的OJ却是WA?额……似乎也没什么问题啊
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')d=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define N 105 int a[N][N],l[N],f[N]; int n,m,flag=0; bool y[N]; struct an { int x,y; }ans[N]; int num=0; bool match(int x) { fo(i,1,n) { if (a[x][i]==0&&y[i]==0) { y[i]=1; if(l[i]==0||match(l[i])) { l[i]=x; return 1; } } } return 0; } int calc() { memset(l,0,sizeof(l)); int t=0; fo(i,1,n) { memset(y,0,sizeof(y)); if(match(i))t++; } return t; } bool com(an a,an b) { return a.x<b.x; } int main() { n=read(); int dx=read(),dy=read(); while(dx+dy!=0) { a[dx][dy]=1; dx=read(),dy=read(); } int fans=calc(); if(fans==n) { fo(i,1,n) f[i]=l[i]; fo(i,1,n) { int t=f[i]; a[f[i]][i]=1; int tans=calc(); a[f[i]][i]=0; if(tans!=n) { ans[++num].x=f[i]; ans[num].y=i; flag=1; } } if(flag==0)printf("none"); else { sort(ans+1,ans+num+1,com); fo(i,1,num) cout<<ans[i].x<<' '<<ans[i].y<<endl; } } else printf("none"); return 0; }