zoukankan      html  css  js  c++  java
  • USACO5.4 奶牛的电信Telecowmunication (最小割,割边转割点)

    题目

    链接

    思路

    看题目就知道是最小割了,但是不一样的是,我们一般求的最小割是割边,而这题让我们求的是割点,那么我们在原有的网络基础上在每个点和一个我们附加的点上连上一条边权为1的边限制流量就好了。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=start;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f=-1;
            ch=getchar();
        } while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        } return x*f;
    }
    const int maxn=3510;
    int head[maxn],cnt=1;
    struct edge {
    	int v,flow,next;
    }e[maxn];
    
    inline void add (int u,int v,int flow) {
    	e[++cnt]= (edge) {v,flow,head[u]};
    	head[u]=cnt;
    }
    
    inline void add_edge (int u,int v,int flow) {
        add (u,v,flow);
    	add (v,u,0);
    }   
    
    int dis[maxn],cur[maxn];
    int s,t,n,m,c1,c2;
    int bfs () {
       MT (dis,0);
       queue <int > q;
       dis[s]=1;
       q.push (s);
       while (q.size ()) {
          int x=q.front (); q.pop ();
    	  for (int i=head[x];~i;i=e[i].next) {
    		  if (dis[e[i].v]==0&&e[i].flow) {
    			  dis[e[i].v]=dis[x]+1;
    			  q.push (e[i].v);
    		  }
    	  }
       }
       return dis[t];
    }
    
    int dfs  (int now,int nowflow) {
    	if (now==t) return nowflow;
    	for (int &i=cur[now];i!=-1;i=e[i].next) {
            if (dis[e[i].v]==dis[now]+1&&e[i].flow) {
    			int canflow=dfs (e[i].v,min (e[i].flow,nowflow));
    			if (canflow) {
    				e[i].flow-=canflow;
    				e[i^1].flow+=canflow;
    				return canflow;
    			}
    		}
    	} 
    	return 0;
    }
    
    int ans=0;
    void Dinic () {
    	while (bfs ()) {
    		memcpy (cur,head,sizeof (cur));
    		while (int val=dfs (s,inf)) ans+=val;
    	}
    }
    
    int main () {
    	MT (head,-1);
    	scanf ("%d%d%d%d",&n,&m,&s,&t);
    	s+=n;
    	rep (i,1,n) add_edge (i,i+n,1);
    	rep (i,1,m) {
    		int x,y;
    		scanf ("%d%d",&x,&y);
    		add_edge (x+n,y,inf);
    		add_edge (y+n,x,inf);
    	}
    	Dinic ();
        cout<<ans<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    es5预览本地文件、es6练习代码演示案例
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 836 矩形重叠(暴力)
    Subversion under Linux [Reprint]
    Subversion how[Reprint]
  • 原文地址:https://www.cnblogs.com/hhlya/p/13543126.html
Copyright © 2011-2022 走看看