我是参考的这篇题解
为啥枚举时,S<=2而不是S<=N,S<=N会爆
下面是我的代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#define INF 0x3f3f3f3f
#define N 210
#define M 5010
using namespace std;
int n,m,a[M],b[M],S,T,ans,minn;
int vis[N],inq[N],tot,pre[N];
int edge[M],len[M],nxt[M],head[N];
queue<int> q;
void add(int x,int y,int z)
{
edge[++tot]=y;
nxt[tot]=head[x];
len[tot]=z;
head[x]=tot;
edge[++tot]=x;
nxt[tot]=head[y];
head[y]=tot;
len[tot]=0;//双向边
}
int read()
{
int v=0,f=1;char c='_';
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
v=v*10+c-'0';
c=getchar();
}
return v*f;
}
int BFS()
{
memset(vis,0,sizeof(vis));
while(q.size()) q.pop();
q.push(S);inq[S]=INF;
vis[S]=1;
while(q.size())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=nxt[i])
{
int y=edge[i];
if(len[i]&&!vis[y])
{
pre[y]=i;
inq[y]=min(inq[x],len[i]);//flow=min(len[i],flow);
if(y==T) return 1;
q.push(y);vis[y]=1;
}
}
}
return 0;
}//不熟练
void EK()
{
int x=T;
while(x!=S)//while(x)
{
int y=pre[x];
len[y]-=inq[T];
len[y^1]+=inq[T];
x=edge[y^1];//不会 x=[x^1];
}
minn+=inq[T];
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)//cin>>n>>m&&n
{
for(int i=1;i<=m;i++)//这儿必须用快读
a[i]=read()+1,b[i]=read()+1;//cin>>x>>y;
ans=INF;
for(S=1;S<=2;S++)//S<=N
for(T=1;T<=n;T++)
if(S!=T)
{
memset(head,0,sizeof(head));tot=1;//tot=0;
for(int i=1;i<=n;i++)
{
if(i==S||i==T) add(i,i+n,INF);
else add(i,i+n,1);
}
for(int i=1;i<=m;i++)
{
add(b[i]+n,a[i],INF);
add(a[i]+n,b[i],INF);
}
minn=0;
while(BFS()) EK();
ans=min(ans,minn);
}
if(ans==INF||n<=1) cout<<n<<endl;//???
else cout<<ans<<endl;
}
return 0;
}