有限电视网络


给定无向图 最少去掉多少个点可以让图不连通

如果有割点 那么答案是1
所以不能用tarjan做法 而应该采用网络流做法 题目这种要求和最小割很类似

#include 
#include 
#include 
#include 
#define pa pair
#define mp make_pair
#define fs first
#define sc second
using namespace std;

const int N=105;
const int M=5000;
const int INF=0x3f3f3f3f;

int read()
{
	int x=0,f=0,c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return f?-x:x;
}

struct Edge
{
	int to,next,w;
}e[M];
int head[N],cnt=1;
void _add(int a,int b,int c){  e[++cnt]=(Edge){b,head[a],c}; head[a]=cnt;}
void add(int a,int b,int c){ _add(a,b,c);_add(b,a,0);}
int n,m,S,T;
bool atl[55][55];
pa p[M];

queue q;int d[N];
bool bfs()
{
	while(q.size()) q.pop();
	memset(d,0,sizeof d);
	q.push(S+n); d[S+n]=1;
	while(q.size())
	{
		int x=q.front(); q.pop();
		for(int i=head[x];i;i=e[i].next)
		{
			int y=e[i].to;
			if(!e[i].w||d[y]) continue;
			d[y]=d[x]+1; q.push(y);
			if(y==T) return 1;
		}
	}
	return 0;
}

int dinic(int x,int flow)
{
	if(x==T) return flow;
	int rest=flow;
	for(int i=head[x];i&&rest;i=e[i].next)
	{
		int y=e[i].to;
		if(e[i].w&&d[y]==d[x]+1)
		{
			int k=dinic(y,min(rest,e[i].w));
			if(!k) d[y]=0;
			e[i].w-=k; e[i^1].w+=k; rest-=k;
		}
	}
	return flow-rest;
}

int main()
{	
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(atl,0,sizeof atl);	
		if(!m&&n==1){printf("%d\n",n);continue;}
		getchar();
		for(int i=1;i<=m;i++)
		{
			getchar(); 
			int x=read()+1;int y=read()+1; 
			atl[x][y]=1; atl[y][x]=1;
			p[i]=mp(x,y);
		}
		int ans=INF,flow=0,maxflow=0;
		for(S=1;S<=n;S++)
			for(T=S+1;T<=n;T++)
			{

				if(atl[S][T]) { ans=min(ans,n); continue;}		
				
				memset(head,0,sizeof head); cnt=1;	
				for(int i=1;i<=m;i++) 
					add(p[i].fs+n,p[i].sc,INF),add(p[i].sc+n,p[i].fs,INF);
				for(int i=1;i<=n;i++) 
					if(i!=S&&i!=T) add(i,i+n,1);	
				maxflow=0; 
					
				while(bfs()) 
					while(flow=dinic(S+n,INF)) maxflow+=flow;	
			
				ans=min(ans,maxflow);
			}
		if(ans==INF) ans=0;
		printf("%d\n",ans);
	}
	return 0;
}

注意:
//S点T点不拆开
//每次都必须重新建图 因为dinic涉及到了图的修改,对应的maxflow也要清零
//网络流中 每一个add视为一条有向边 因此如果是双向边的话 还需要加两边边

相关