#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define Min(a,b) a<b?a:b
using namespace std;
const int maxn = 200;
const int INF = 1<<30;
struct edge
{
int from,to,cap,flow;
};
vector<edge> edges;
vector<int> g[maxn];
int p[maxn],a[maxn];
bool d[maxn][maxn];
int n,m;
void addedge(int from,int to,int cap)
{
edges.push_back(edge{from,to,cap,0});
edges.push_back(edge{to,from,0,0});
int m=edges.size();
g[from].push_back(m-2);
g[to].push_back(m-1);
}
int maxflow(int s,int t)
{
int flow=0;
bool mark=1;
for(int i=0;i<edges.size();i++)edges[i].flow=0;
while(1)
{
queue<int> q;
memset(a,0,sizeof(a));
a[s]=INF;
q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<g[u].size();i++)
{
edge &e = edges[g[u][i]];
if(!a[e.to]&&e.cap-e.flow>0)
{
a[e.to]=Min(a[u],e.cap-e.flow);
p[e.to]=g[u][i];
q.push(e.to);
}
}
if(a[t])break;
}
if(mark&&!a[t])return -1;
else mark=0;
if(!a[t])break;
for(int i=t;i!=s;i=edges[p[i]].from)
{
edges[p[i]].flow+=a[t];
edges[p[i]^1].flow-=a[t];
}
flow+=a[t];
}
return flow;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int mmin=1<<30;
for(int i=0;i<maxn;i++)g[i].clear();
edges.clear();
memset(d,0,sizeof(d));
for(int i=0;i<n;i++)//拆点
{
addedge(i,i+n,1);
addedge(i+n,i,1);
}
int u,v;
for(int i=0;i<m;i++)
{
scanf(" (%d,%d)",&u,&v);
addedge(u,v+n,INF);
addedge(v,u+n,INF);
d[u][v]=d[v][u]=1;
}
for(int i=1;i<n;i++)
{
if(!d[0][i])
{
int ans=maxflow(0,i+n);
if(mmin>ans)mmin=ans;
if(mmin==-1)
{
mmin=0;break;
}
}
}
if(mmin==INF)mmin=n;
printf("%d\n",mmin);
}
}
vua 1660 Cable TV Network 最大流最小割 求割点
最新推荐文章于 2024-03-14 10:27:30 发布