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

    题意:给一幅图,从1开始,每条边有边权最少走一遍,可以在任意点退出,问最小花费
    题解:上下界费用流,每个边都流一遍,然后为了保证流量平衡,新建源点汇点,跑费用流把流量平衡

    /**************************************************************
        Problem: 3876
        User: walfy
        Language: C++
        Result: Accepted
        Time:140 ms
        Memory:2868 kb
    ****************************************************************/
     
    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000009
    #define ld long double
    //#define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define ull unsigned long long
    //#define base 1000000000000000000
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
     
    using namespace std;
     
    const ull ba=233;
    const db eps=1e-5;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=500+10,maxn=100000+10,inf=0x3f3f3f3f;
     
    bool vis[N];
    int cnt,head[N],pre[N],path[N],dis[N],in[N],out[N];
    struct edge{int to,Next,c,cost;}e[maxn];
    void init(){memset(head,-1,sizeof head);cnt=0;}
    void add(int u,int v,int c,int cost)
    {
    //    printf("%d %d %d %lld
    ",u,v,c,cost);
        e[cnt].to=v;e[cnt].c=c;e[cnt].cost=cost;e[cnt].Next=head[u];head[u]=cnt++;
        e[cnt].to=u;e[cnt].c=0;e[cnt].cost=-cost;e[cnt].Next=head[v];head[v]=cnt++;
    }
    bool spfa(int s,int t)
    {
        memset(pre,-1,sizeof pre);
        memset(dis,inf,sizeof dis);
        memset(vis,0,sizeof vis);
        dis[s]=0;vis[s]=1;
        queue<int>q;q.push(s);
        while(!q.empty())
        {
            int x=q.front();q.pop();
            vis[x]=0;
            for(int i=head[x];~i;i=e[i].Next)
            {
                int te=e[i].to;
                if(e[i].c>0&&dis[x]+e[i].cost<dis[te])
                {
                    dis[te]=dis[x]+e[i].cost;
                    pre[te]=x;path[te]=i;
                    if(!vis[te])q.push(te),vis[te]=1;
                }
            }
        }
        return pre[t]!=-1;
    }
    int mincostmaxflow(int s,int t)
    {
        int cost=0,flow=0;
        while(spfa(s,t))
        {
            int f=inf;
            for(int i=t;i!=s;i=pre[i])
                if(e[path[i]].c<f)
                   f=e[path[i]].c;
            flow+=f;cost+=dis[t]*f;
            for(int i=t;i!=s;i=pre[i])
            {
                e[path[i]].c-=f;
                e[path[i]^1].c+=f;
            }
        }
        return cost;
    }
    int main()
    {
        init();
        int n,tot=0;scanf("%d",&n);
        int s=1,t=n+1,ss=n+2,tt=n+3,ans=0;
        for(int i=1,k;i<=n;i++)
        {
            for(scanf("%d",&k);k;k--)
            {
                int a,b;scanf("%d%d",&a,&b);
                add(i,a,5000,b);
                out[i]++,in[a]++;ans+=b;
            }
            add(i,t,5000,0);
        }
        add(t,s,5000,0);
        for(int i=1;i<=n;i++)
        {
            if(in[i]>out[i])add(ss,i,in[i]-out[i],0);
            else add(i,tt,out[i]-in[i],0);
        }
        ans+=mincostmaxflow(ss,tt);
        printf("%d
    ",ans);
        return 0;
    }
    /********************
    6
    2 2 1 3 2
    2 4 3 5 4
    2 5 5 6 6
    0
    0
    0
    ********************/
    
  • 相关阅读:
    Pycharm使用
    解决TortoiseGit下载代码每次要输入用户名、密码
    GitLab创建项目
    【编码格式错误】SyntaxError: Non-UTF-8 code starting with
    C 位段,位域
    跳跃表 -- 随机平衡原理
    PHP 中的新语法 new static 是个啥意思?
    位运算之——按位与(&)操作——(快速取模算法)
    Redis Scan迭代器遍历操作原理(一)
    Redis Scan迭代器遍历操作原理(二)
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10484272.html
Copyright © 2011-2022 走看看