zoukankan      html  css  js  c++  java
  • BZOJ3876: [Ahoi2014]支线剧情

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3876

    最小费用最小流。

    图是一个拓扑图并要求每条边都要至少走一次求最小花费。

    比如说u连出了k条边,其中一条连向v,费用为w,就u→T(k,0) u→v(inf,w) S→v(1,w) 最后 u→1(inf,0)表示不以1为源点。

    然后跑一遍费用流就可以了。

    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<algorithm>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define low(x) (x&(-x)) 
    #define maxn 505
    #define inf int(1e9)
    #define mm 1000000007
    #define ll long long
    using namespace std;
    int tot=1,n,t,ans;
    int head[maxn],dis[maxn],uu[maxn],cur[maxn];
    struct data{int obj,pre,c,w;
    }e[500500];
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    void insert(int x,int y,int c,int w){
        e[++tot].obj=y; e[tot].pre=head[x]; e[tot].c=c; e[tot].w=w; head[x]=tot;
        e[++tot].obj=x; e[tot].pre=head[y]; e[tot].c=0; e[tot].w=-w; head[y]=tot;
    }
    bool spfa(){
        clr(uu,0);
        rep(i,0,t) dis[i]=inf; dis[0]=0;
        queue<int> q; q.push(0);
        while (!q.empty()){
            int u=q.front(); q.pop(); uu[u]=1;
            for (int j=head[u];j;j=e[j].pre){
                int v=e[j].obj;
                if (e[j].c>0&&dis[v]>dis[u]+e[j].w){
                    dis[v]=dis[u]+e[j].w;
                    if (uu[v]==0) uu[v]=1,q.push(v);
                }
            }
            uu[u]=0;
        }
        if (dis[t]>=inf) return 0;
        return 1;
    }
    int dfs(int x,int mx){
        //if (uu[x]==1) return 0;
        if (x==t||mx==0) return mx;
        uu[x]=1;
        int used=0;
        for (int j=cur[x];j;j=e[j].pre){
            int v=e[j].obj;
            if (dis[v]==dis[x]+e[j].w&&e[j].c>0&&uu[v]==0){
                int w=dfs(v,min(e[j].c,mx-used));
                ans+=w*e[j].w; 
                e[j].c-=w; e[j^1].c+=w; used+=w;
                cur[x]=j;
                if (used==mx) return used;
            }
        }
        return used;
    }
    int main(){
        n=read();
        t=n+1;
        rep(i,1,n){
            int k=read();
            insert(i,1,inf,0);
            insert(i,t,k,0);
            rep(j,1,k){
                int x=read(), y=read();
                insert(i,x,inf,y);
                insert(0,x,1,y);
            }
        }
        while (spfa()){
            clr(uu,0); rep(i,0,t) cur[i]=head[i];
            dfs(0,inf);
        }
        printf("%d
    ",ans);
        return 0;
    } 
  • 相关阅读:
    《棉花帝国:一部资本主义全球史》笔记
    关于”空杯之心“的重新思考
    《光荣与梦想:19321972年美国叙事史》笔记
    《哥伦布大交换:1492年以后的生物影响和文化冲击》笔记
    《增长、短缺与效率》笔记
    《逃不开的经济周期:历史、理论与投资现实》笔记
    《经济学》笔记
    《就业、利息和货币通论》笔记
    PostgreSQL与MySQL比较
    让svn自动更新代码注释中的版本号
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5131393.html
Copyright © 2011-2022 走看看