zoukankan      html  css  js  c++  java
  • 最小割树

    最小割树

    快速求无向图两点间的最小割

    分治建立:

    1. 区间内任选两点(x,y),跑最小割,连边((x,y,cut_{x,y}))
    2. 根据此最小割,把点割成两部分,递归处理
    3. 新建出的树,两点路径上的最小值即为他们在原图上的最小割

    时间复杂度(O(n^3m)),但网络流很难卡满

    正确性证明


    (N850M8500)

    最小割树板题

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f==1?x:-x;
    }
    const int N=852,M=17004,inf=0x3f3f3f3f;
    int n,m,p[N],p1[N];
    set<int>s;
    inline void add(int u,int v,int w){
    	s.insert(w);
    }
    namespace gragh{
    	struct edge{
    		int v,f,yf,nxt;
    	}e[M];
    	int first[N],cnt=1,cur[N],s,t,cn=0,vis[N],dep[N];
    	inline void add(int u,int v,int w){
    		e[++cnt]=(edge){v,w,w,first[u]};first[u]=cnt;
    		e[++cnt]=(edge){u,w,w,first[v]};first[v]=cnt;
    	}
    	inline bool bfs(){
    		static queue<int>q;
    		while(!q.empty())q.pop();
    		memset(dep,-1,sizeof(dep));
    		dep[s]=1;q.push(s);
    		while(!q.empty()){
    			int x=q.front();q.pop();
    			for(int i=first[x],v;i;i=e[i].nxt){
    				v=e[i].v;
    				if(e[i].f&&dep[v]==-1){
    					dep[v]=dep[x]+1;
    					if(v==t)return 1;
    					q.push(v);
    				}
    			}
    		} 
    		return 0;
    	}
    	int dfs(int x,int f){
    		if(x==t||!f)return f;
    		int used=0;
    		for(int &i=cur[x],v,w;i;i=e[i].nxt){
    			v=e[i].v;
    			if(!e[i].f||dep[v]!=dep[x]+1)continue;
    			w=dfs(v,min(f,e[i].f));
    			if(!w)continue;
    			e[i].f-=w;e[i^1].f+=w;
    			f-=w;used+=w;
    			if(!f)break;
    		}
    		return used;
    	}
    	inline int dinic(int u,int v){
    		s=u;t=v;
    		for(int i=2;i<=cnt;i++)e[i].f=e[i].yf;
    		int flow=0;
    		while(bfs()){
    			memcpy(cur,first,sizeof(first));
    			flow+=dfs(s,inf);
    		}
    		return flow;
    	}
    	void dfs(int x){
    		vis[x]=cn;
    		for(int i=first[x],v;i;i=e[i].nxt){
    			v=e[i].v;
    			if(e[i].f&&vis[v]!=cn)dfs(v);
    		}
    	}
    	void build(int l,int r){
    		if(l>=r)return;
    		int x=p[l],y=p[l+1],ll=l,rr=r;
    		int cut=dinic(x,y);
    		cn++;dfs(x);
    		for(int i=l;i<=r;i++)
    			if(vis[p[i]]==cn)p1[ll++]=p[i];
    			else p1[rr--]=p[i];
    		for(int i=l;i<=r;i++)p[i]=p1[i];
    		::add(x,y,cut);
    		build(l,ll-1);build(rr+1,r);
    	}
    }
    int main(){
    	n=read();m=read();
    	for(int i=1,u,v,w;i<=m;i++){
    		u=read();v=read();w=read();
    		gragh::add(u,v,w);
    	} 
    	for(int i=1;i<=n;i++)p[i]=i;
    	gragh::build(1,n);
    	cout<<s.size(); 
    	return (0-0);
    }
    
  • 相关阅读:
    设计模式(2)——工厂模式详解
    直观理解梯度,以及偏导数、方向导数和法向量等
    如何编译和调试Python内核源码?
    VGG(2014),3x3卷积的胜利
    Network in Network(2013),1x1卷积与Global Average Pooling
    ZFNet(2013)及可视化的开端
    一文搞懂 deconvolution、transposed convolution、sub-­pixel or fractional convolution
    从AlexNet(2012)开始
    ImageNet主要网络benchmark对比
    仿射变换及其变换矩阵的理解
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12567811.html
Copyright © 2011-2022 走看看