【模考】2018.04.08 Connection Description Input Output Sample Input Sample Output Data Constraint Solution

【模考】2018.04.08 Connection
Description
Input
Output
Sample Input
Sample Output
Data Constraint
Solution

给定一张N个点M条边的连通无向图,问最少需要断开多少条边使得这张图不再连通。

Input

第一行两个整数N,M含义如题所示。
接下来M行,每行两个正整数x,y,表示x和y之间有一条无向边。
输入数据保证连通性且无自环。

Output

输出最少需要断开多少条边。

Sample Input

5 7
1 2
2 3
3 4
4 5
5 1
2 4
1 3

Sample Output

2

Data Constraint

【模考】2018.04.08 Connection
Description
Input
Output
Sample Input
Sample Output
Data Constraint
Solution

Solution

强大的做法:由于最优割法中1号点一定与另一个节点在不同的联通块中,所以直接枚举1号点是与哪一号点分开,然后跑网络流求最小割,chkmin每次的答案就可以了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=3000+10,MAXM=10000+10,inf=0x3f3f3f3f;
int n,m,ans=inf;
struct edge{
	int u,v;
};
edge side[MAXM];
template<typename T> inline void read(T &x)
{
	T data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
	x=data*w;
}
template<typename T> inline void write(T x,char c=' ')
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
	if(c!=' ')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
struct maxflow{
	int e,to[MAXM<<1],nex[MAXM<<1],beg[MAXN],s,t,cap[MAXN<<1],level[MAXN],cur[MAXN];
	std::queue<int> q;
	inline void init()
	{
		e=1;
		memset(beg,0,sizeof(beg));
		memset(cap,0,sizeof(cap));
	}
	inline void insert(int x,int y,int z)
	{
		to[++e]=y;
		nex[e]=beg[x];
		beg[x]=e;
		cap[e]=z;
		to[++e]=x;
		nex[e]=beg[y];
		beg[y]=e;
		cap[e]=z;
	}
	inline bool bfs()
	{
		memset(level,0,sizeof(level));
		level[s]=1;
		q.push(s);
		while(!q.empty())
		{
			int x=q.front();
			q.pop();
			for(register int i=beg[x];i;i=nex[i])
				if(!level[to[i]]&&cap[i])level[to[i]]=level[x]+1,q.push(to[i]);
		}
		return level[t];
	}
	inline int dfs(int x,int maxflow)
	{
		if(x==t||!maxflow)return maxflow;
		int res=0,f;
		for(register int &i=cur[x];i;i=nex[i])
			if(cap[i]&&level[to[i]]==level[x]+1)
			{
				f=dfs(to[i],min(maxflow,cap[i]));
				cap[i]-=f;
				cap[i^1]+=f;
				maxflow-=f;
				res+=f;
				if(!maxflow)break;
			}
		return res;
	}
	inline int Dinic()
	{
		int res=0;
		while(bfs())memcpy(cur,beg,sizeof(cur)),res+=dfs(s,inf);
		return res;
	}
	inline int solve(int x,int y)
	{
		init();
		s=x,t=y;
		for(register int i=1;i<=m;++i)insert(side[i].u,side[i].v,1);
		return Dinic();
	}
};
maxflow G;
int main()
{
	read(n);read(m);
	for(register int i=1;i<=m;++i)read(side[i].u),read(side[i].v);
	for(register int i=2;i<=n;++i)chkmin(ans,G.solve(1,i));
	write(ans,'
');
	return 0;
}