zoukankan      html  css  js  c++  java
  • 【BZOJ4519】不同的最小割(CQOI2016)-最小割树

    测试地址:不同的最小割
    做法:本题需要用到最小割树。
    看到两两间的最小割,就想到最小割树了,于是仿照BZOJ2229那题建最小割树,最后树上有多少不同的边权就等同于有多少不同的最小割。其实连树都不用建出来,直接用一个数组存储出现的最小割,最后排一次序就行了。
    (厚颜无耻的我复制粘贴了BZOJ2229的代码……如果里面有一些奇怪的东西也不要惊讶)
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll inf=(ll)1000000000*(ll)1000000000;
    int n,m,first[1010]={0},tot=1,p[1010],S[1010],T[1010];
    int h,t,q[1010],lvl[1010],cur[1010];
    ll f[1010];
    bool vis[1010];
    struct edge
    {
        int v,next;
        ll used,f;
    }e[100010];
    
    void insert(int a,int b,ll f)
    {
        e[++tot].v=b,e[tot].next=first[a],e[tot].used=f,first[a]=tot;
        e[++tot].v=a,e[tot].next=first[b],e[tot].used=f,first[b]=tot;
    }
    
    bool makelevel(int S,int T)
    {
        for(int i=1;i<=n;i++)
            lvl[i]=-1,cur[i]=first[i];
        lvl[S]=0;
        h=t=1;
        q[1]=S;
        while(h<=t)
        {
            int v=q[h++];
            for(int i=first[v];i;i=e[i].next)
                if (e[i].f&&lvl[e[i].v]==-1)
                {
                    lvl[e[i].v]=lvl[v]+1;
                    q[++t]=e[i].v;
                }
        }
        return lvl[T]!=-1;
    }
    
    ll maxflow(int v,ll maxf,int T)
    {
        ll ret=0,f;
        if (v==T) return maxf;
        for(int i=cur[v];i;i=e[i].next)
        {
            if (e[i].f&&lvl[e[i].v]==lvl[v]+1)
            {
                f=maxflow(e[i].v,min(maxf-ret,e[i].f),T);
                ret+=f;
                e[i].f-=f;
                e[i^1].f+=f;
                if (ret==maxf) break;
            }
            cur[v]=i;
        }
        if (!ret) lvl[v]=-1;
        return ret;
    }
    
    ll dinic(int S,int T)
    {
        ll maxf=0;
        for(int i=2;i<=(m<<1)+1;i++)
            e[i].f=e[i].used;
        while(makelevel(S,T))
            maxf+=maxflow(S,inf,T);
        return maxf;
    }
    
    void findS(int v)
    {
        vis[v]=1;
        for(int i=first[v];i;i=e[i].next)
            if (e[i].f&&!vis[e[i].v]) findS(e[i].v);
    }
    
    void solve(int l,int r)
    {
        if (l==r) return;
        int s=dinic(p[l],p[r]);
        f[++tot]=s;
    
        memset(vis,0,sizeof(vis));
        findS(p[l]);
        S[0]=T[0]=0;
        for(int i=l;i<=r;i++)
        {
            if (vis[p[i]]) S[++S[0]]=p[i];
            else T[++T[0]]=p[i];
        }
        for(int i=1;i<=S[0];i++)
            p[l+i-1]=S[i];
        for(int i=1;i<=T[0];i++)
            p[l+S[0]+i-1]=T[i];
    
        int sizS=S[0];
        solve(l,l+sizS-1);
        solve(l+sizS,r);
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int u,v;
            ll c;
            scanf("%d%d%lld",&u,&v,&c);
            insert(u,v,c);
        }
    
        tot=0;
        for(int i=1;i<=n;i++)
            p[i]=i;
        solve(1,n);
        sort(f+1,f+n);
    
        int ans=0;
        for(int i=1;i<n;i++)
            if (i==1||f[i]!=f[i-1]) ans++;
        printf("%d",ans);
    
        return 0;
    }
  • 相关阅读:
    ASP.NET 表单验证 Part.1(理解表单验证)
    Silverlight 简介 Part.3(设计 Siverlight 页面)
    ASP.NET 成员资格 Part.3(LoginStatus、LoginView、PasswordRecovery)
    ASP.NET 网站部署 Part.1(安装IIS、复制文件部署网站)
    ASP.NET Dynamic Data Part.1(创建动态数据应用程序)
    ASP.NET 安全模型 Part.2(SSL)
    ASP.NET MVC Part.2(扩展基本的 MVC 应用程序)
    ASP.NET 网站部署 Part.2(使用 Web 部署)
    开发高级 Web 部件
    创建 Web 部件(WebPart 类、简单的 Web 部件)
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793437.html
Copyright © 2011-2022 走看看