zoukankan      html  css  js  c++  java
  • AcWing 381. 有线电视网络

    有线电视网络

    Solution

    网络流建模
    wam9g0.png
    wanaFJ.png
    源点枚举的是点的出点,汇点枚举的是点的入点。
    但如果仅仅这样的话,我们发现网络流中的最小割与原问题的解不是一一对应的。
    这是因为最小割中一定不包括源点和汇点,
    但是只要原问题的解最后余下两个点以上,这种方案已经包括在最小割中了。
    所以我们分别考虑最后只余下一个点和零个点的情况,

    • 一个点的话,图还连通,不符题意。
    • 零个点的话,符合题意,需要割掉的点数为n。

    ans=min(n,maxflow)

    Code

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    typedef long long LL;
    typedef unsigned long long ULL;
    using namespace std;
    const int N=500,M=1e4+5,INF=1e9+5;
    int one[N],idx=1;
    int ver[M],Next[M],edge[M],e[M];
    inline void AddEdge(int a,int b,int c)
    {
    	Next[++idx]=one[a];
    	one[a]=idx;
    	ver[idx]=b;
    	e[idx]=c;
    //	printf("%d ---> %d
    ",a,b);
    	return;
    }
    //============================
    int n,m,S,T;
    queue<int> q;
    int d[N],cur[N];
    bool bfs()
    {
    	memset(d,-1,sizeof d);
    	memcpy(cur,one,sizeof cur);
    	while(q.size()) q.pop();
    	int i,x,y;
    	q.push(S); d[S]=1;
    	while(q.size()) {
    		x=q.front(); q.pop();
    		for(i=one[x];i>0;i=Next[i]) {
    			y=ver[i];
    			if(edge[i] && d[y]==-1) {
    				d[y]=d[x]+1;
    				if(y==T) return true;
    				q.push(y);
    			}
    		}
    	}
    	return false;
    }
    int dinic(int x,int limit)
    {
    	if(x==T) return limit;
    	int i,y,flow=0,k;
    	for(i=cur[x];i>0 && flow<limit;i=Next[i]) {
    		cur[x]=i;
    		y=ver[i];
    		if(edge[i] && d[y]==d[x]+1) {
    			k=dinic(y,min(edge[i],limit-flow));
    			if(k==0) d[y]=-1;
    			edge[i]-=k; edge[i^1]+=k;
    			flow+=k;
    		}
    	}
    	return flow;
    }
    int main()
    {
    //	freopen("1.in","r",stdin);
    	int i,x,y;
    	int ans,maxflow;
    	char c;
    	while(scanf("%d%d",&n,&m)==2) {
    		memset(one,0,sizeof one);
    		memset(ver,0,sizeof ver);
    		memset(e,0,sizeof e);
    		memset(Next,0,sizeof Next);
    		idx=1;
    		
    		for(i=1;i<=m;i++) {
    			cin>>c;
    			scanf("%d,%d",&x,&y);
    			cin>>c;
    			x++; y++;
    			AddEdge(x+n,y,INF);
    			AddEdge(y,x+n,0);
    			AddEdge(y+n,x,INF);
    			AddEdge(x,y+n,0);	
    		}
    		for(i=1;i<=n;i++) 
    			AddEdge(i,i+n,1),AddEdge(i+n,i,0);
    		ans=n;
    		for(S=n+1;S<=2*n;S++) 
    			for(T=S-n+1;T<=n;T++) {
    				memcpy(edge,e,sizeof edge);
    				maxflow=0;
    				while(bfs()) 
    					while((x=dinic(S,INF))) 
    						maxflow+=x;
    				ans=min(ans,maxflow);
    			}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    HDU 4763 Theme Section(KMP+枚举公共前后缀)
    HDU 3613 Best Reward(扩展KMP求前后缀回文串)
    HDU 3613 Best Reward(manacher求前、后缀回文串)
    扩展KMP模板
    Vue
    Vue
    css 文本换行 文本溢出隐藏用省略号表示剩下内容
    sublime 神一样的插件
    markdown
    css 居中布局
  • 原文地址:https://www.cnblogs.com/cjl-world/p/14054140.html
Copyright © 2011-2022 走看看