zoukankan      html  css  js  c++  java
  • BZOJ 4519 [CQOI2016]不同的最小割

    这道题目很奇怪.

    为什么奇怪?因为这道题用了一种叫分治最小割/最小割树的玩意.

    以前从来没有见过这东西.

    推荐一个讲这玩意的博客

    写起来还是很顺手的.

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #include<string>
    #include<iomanip>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define ll long long
    #define FILE "dealing"
    #define up(i,j,n) for(int i=j;i<=n;++i)
    #define db double
    #define uint unsigned ll
    #define eps 1e-12
    #define pii pair<ll,ll>
    ll read(){
    	ll x=0,f=1,ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	return f*x;
    }
    const ll maxn=20500,limit=1e6,mod=(ll)(7+1e9+0.1);
    const ll inf=(ll)(1e9);
    template<class T>bool cmax(T& a,T b){return a<b?a=b,true:false;}
    template<class T>bool cmin(T& a,T b){return a>b?a=b,true:false;}
    template<class T>T min(T& a,T& b){return a<b?a:b;}
    template<class T>T max(T& a,T& b){return a>b?a:b;}
    int n,m,S,T,id[maxn],vis[maxn],tmp[maxn],w[maxn],tot=0;
    struct node{
    	int y,next,flow,rev;
    }e[maxn];
    int len=1,linkk[maxn];
    void insert(int x,int y,int flow){
    	e[++len].y=y;
    	e[len].next=linkk[x];
    	linkk[x]=len;
    	e[len].flow=flow;
    	e[len].rev=len+1;
    	e[++len].y=x;
    	e[len].next=linkk[y];
    	linkk[y]=len;
    	e[len].flow=flow;
    	e[len].rev=len-1;
    }
    int d[maxn],q[maxn],head,tail;
    bool makelevel(){
    	up(i,1,n)d[i]=-1;
    	d[S]=0;head=tail=0;
    	q[++tail]=S;
    	while(++head<=tail){
    		int x=q[head];
    		for(int i=linkk[x];i;i=e[i].next)
    			if(d[e[i].y]==-1&&e[i].flow)d[e[i].y]=d[x]+1,q[++tail]=e[i].y;
    	}
    	return d[T]!=-1;
    }
    int makeflow(int x,int flow){
    	if(x==T||!flow)return flow;
    	int maxflow=0,dis=0;
    	for(int i=linkk[x];i&&maxflow<flow;i=e[i].next){
    		if(d[e[i].y]==d[x]+1&&e[i].flow)
    			if(dis=makeflow(e[i].y,min(flow-maxflow,e[i].flow))){
    				e[i].flow-=dis;
    				e[i^1].flow+=dis;
    				maxflow+=dis;
    			}
    	}
    	if(!maxflow)d[x]=-1;
    	return maxflow;
    }
    int dinic(){
    	int ans=0,d;
    	while(makelevel())
    		while(d=makeflow(S,inf))
    			ans+=d;
    	return ans;
    }
    void dfs(int x){
    	vis[x]=1;
    	for(int i=linkk[x];i;i=e[i].next){
    		if(e[i].flow&&!vis[e[i].y])
    			dfs(e[i].y);
    	}
    }
    void divide(int l,int r){
    	if(l==r)return;
    	for(int i=2;i<=len;i+=2)
    		e[i].flow=e[i^1].flow=(e[i].flow+e[i^1].flow)>>1;
    	S=id[l],T=id[r];
    	int maxflow=dinic();
    	w[++tot]=maxflow;
    	up(i,1,n)vis[i]=0;
    	dfs(S);
    	int L=l,R=r;
    	up(i,l,r){
    		if(vis[id[i]])tmp[L++]=id[i];
    		else tmp[R--]=id[i];
    	}
    	up(i,l,r)id[i]=tmp[i];
    	divide(l,L-1);divide(R+1,r);
    }
    int main(){
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    	n=read(),m=read();
    	up(i,1,n)id[i]=i;
    	up(i,1,m){
    		int x=read(),y=read(),v=read();
    		insert(x,y,v);
    	}
    	divide(1,n);
    	sort(w+1,w+tot+1);
    	w[0]=-1;
    	int ans=0;
    	up(i,1,tot)if(w[i]!=w[i-1])ans++;
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    iOS初级博客的链接
    代理参数问题的思考
    数组里面的选择排序与起泡排序比较
    【C语言】02-函数
    【C语言】01-第一个c程序代码分析
    响应者链的事件分发
    UIController中view的记载流程
    UITabBar的定制
    CommandTabel_代理方法
    来到博客园
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6544704.html
Copyright © 2011-2022 走看看