zoukankan      html  css  js  c++  java
  • bzoj 4464 : [Jsoi2013]旅行时的困惑

    网络流建图。

    从S向每个点连边,从每个点向T连边。

    每条树边反向连一条下界为1,上界inf的边。

    跑最小流。

    注意加当前弧优化。

    #include<cstdio>
    #include<algorithm>
    #define inf 0x3f3f3f3f
    #define N 500005
    #define M 5000005
    using namespace std;
    int head[N],ver[M],nxt[M],f[M],tot,ch[N],cur[M];
    void add(int a,int b,int c)
    {
        tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;f[tot]=c;
        tot++;nxt[tot]=head[b];head[b]=tot;ver[tot]=a;f[tot]=0;
        return ;
    }
    int S,T,tim;
    int vis[100005],q[M];
    bool tell()
    {
        tim++;
        int l=1,r=1;q[1]=S;
        ch[S]=0;vis[S]=tim;
        while(l<=r)
        {
            int tmp=q[l++];
            for(int i=head[tmp];i;i=nxt[i])
            {
                if(f[i]&&vis[ver[i]]!=tim)
                {
                    ch[ver[i]]=ch[tmp]+1;
                    vis[ver[i]]=tim;
                    q[++r]=ver[i];
                }
            }
        }
        return vis[T]==tim;
    }
    int zeng(int a,int b)
    {
        if(a==T)return b;
        int r=0;
        for(int i=cur[a];i&&b>r;i=nxt[i])
        {
            if(ch[ver[i]]==ch[a]+1&&f[i])
            {
                int t=zeng(ver[i],min(b-r,f[i]));
                r+=t;f[i]-=t;f[i^1]+=t;
                if(f[i]>0)cur[a]=i;
            }
        }
        if(!r)ch[a]=-1;
        return r;
    }
    int dinic()
    {
        int r=0,t;
        while(tell())
        {
            for(int i=0;i<=T;i++)cur[i]=head[i];
            while(t=zeng(S,inf))r+=t;
        }
        return r;
    }
    int n;
    int ru[N],chu[N];
    int main()
    {
        scanf("%d",&n);int t1,t2;
        tot=1;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&t1,&t2);
            t1++;t2++;
            ru[t2]++;chu[t1]++;
            add(t1,t2,inf);
        }
        int TT=n+1,SS=0;
        for(int i=1;i<=n;i++)
        {
            add(SS,i,inf);add(i,TT,inf);
        }
        S=n+2;T=n+3;
        for(int i=1;i<=n;i++)
        {
            if(chu[i]>ru[i])
            {
                add(i,T,chu[i]-ru[i]);
            }
            else if(ru[i]>chu[i])
            {
                add(S,i,ru[i]-chu[i]);
            }
        }
        dinic();
        add(TT,SS,inf);
        dinic();
        printf("%d
    ",f[tot]);
        return 0;
    }
    

      

  • 相关阅读:
    C#用Infragistics 导入导出Excel
    C#基础---Attribute(标签) 和 reflect(反射) 应用二
    C#基础系列:反射笔记
    反射基础
    NPOI之Excel——合并单元格、设置样式、输入公式
    NPOI对Excel的操作(Sheet转DataTable、List<T>)
    【SVN版本回退】
    撤销修改
    iOS
    ios 排序汇总
  • 原文地址:https://www.cnblogs.com/ezyzy/p/7128538.html
Copyright © 2011-2022 走看看