• [bzoj4519][Cqoi2016]不同的最小割_网络流_最小割_最小割树


    不同的最小割 bzoj-4519 Cqoi-2016

    题目大意题目链接

    注释:略。


    想法

    我们发现这和最小割那题比较像。

    我们依然通过那个题说的办法一样,构建最小割树即可。

    接下来就是随便怎么处理都行了。

    我们可以弄一个数组把枚举到的距离都记录下来即可。

    Code

    #include <bits/stdc++.h>
    #define N 860
    #define M 17010
    using namespace std;
    queue<int> q;
    int n,head[N],to[M],val[M],next[M],tot=1,s,t,dis[N],a[N],tmp[N],ans[N][N],v[1000000],tot;
    inline void add(int x,int y,int z)
    {
    	to[++tot]=y,val[tot]=z,next[tot]=head[x],head[x]=tot;
    	to[++tot]=x,val[tot]=z,next[tot]=head[y],head[y]=tot;
    }
    bool bfs()
    {
    	int x,i;
    	memset(dis,0,sizeof(dis));
    	while(!q.empty()) q.pop();
    	dis[s]=1,q.push(s);
    	while(!q.empty())
    	{
    		x=q.front(),q.pop();
    		for(i=head[x];i;i=next[i])
    		{
    			if(val[i]&&!dis[to[i]])
    			{
    				dis[to[i]]=dis[x]+1;
    				if(to[i]==t) return 1;
    				q.push(to[i]);
    			}
    		}
    	}
    	return 0;
    }
    int dinic(int x,int low)
    {
    	if(x==t) return low;
    	int temp=low,i,k;
    	for(i=head[x];i;i=next[i])
    	{
    		if(val[i]&&dis[to[i]]==dis[x]+1)
    		{
    			k=dinic(to[i],min(temp,val[i]));
    			if(!k) dis[to[i]]=0;
    			val[i]-=k,val[i^1]+=k;
    			if(!(temp-=k)) break;
    		}
    	}
    	return low-temp;
    }
    void solve(int l,int r)
    {
    	if(l >= r) return;
    	int i,j,sum=0,p1,p2;
    	for(i=2;i <= tot;i+=2) val[i]=val[i^1]=(val[i]+val[i^1]) >> 1;
    	s=a[l],t=a[r];
    	while(bfs()) sum+=dinic(s,1<<30);
    	for(i=1;i <= n;i++)
    		if(dis[i])
    			for(j=1;j <= n;j++)
    				if(!dis[j])
    					ans[i][j]=ans[j][i]=min(ans[i][j],sum);
    	for(p1=i=l,p2=r;i <= r;i++)
    	{
    		if(dis[a[i]]) tmp[p1++]=a[i];
    		else tmp[p2--]=a[i];
    	}
    	for(i=l;i <= r;i++) a[i]=tmp[i];
    	solve(l,p2),solve(p1,r);
    }
    int main()
    {
    	int m,i,j,x,y,z,ret=0;
    	scanf("%d%d",&n,&m);
    	while(m--) scanf("%d%d%d",&x,&y,&z),add(x,y,z);
    	for(i=1;i <= n;i++) a[i]=i;
    	memset(ans,0x7f,sizeof(ans)),solve(1,n);
    	for(i=1;i <= n;i++)
    		for(j=i+1;j <= n;j++)
    			v[++tot]=ans[i][j];
    	sort(v+1,v+tot+1);
    	v[0]=-1<<30;
    	for(i=1;i <= tot;i++)
    		if(v[i] != v[i-1])
    			ret++;
    	printf("%d
    ",ret);
    	return 0;
    }
    

    小结:最小割树的应用我就碰见了这么两道题。

  • 相关阅读:
    Windows10 + eclipse + JDK1.8 + Apache Maven 3.6.0 + dl4j深度学习环境配置
    vector,deque,list的区别和使用
    extern C的用法解析
    向jupyter notebook加入Anaconda3中已添加的虚拟环境kernel
    TensorFlow学习
    windows10+Python3.6+Anaconda3+tensorflow1.10.0配置和安装
    torchvision
    无oracle客户端仅用plsql连接远程oracle
    poj 3463 Sightseeing(次短路+条数统计)
    10.11 noip模拟试题
  • 原文地址:https://www.cnblogs.com/ShuraK/p/10246211.html
Copyright © 2020-2023  润新知