zoukankan      html  css  js  c++  java
  • Path(2019 杭电多校第一场 ) hdu 6582(最短路模板+dinic模板)

    Path

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 2452    Accepted Submission(s): 677


     

    Problem Description

    Years later, Jerry fell in love with a girl, and he often walks for a long time to pay visits to her. But, because he spends too much time with his girlfriend, Tom feels neglected and wants to prevent him from visiting her.
    After doing some research on the neighbourhood, Tom found that the neighbourhood consists of exactly n houses, and some of them are connected with directed road. To visit his girlfriend, Jerry needs to start from his house indexed 1 and go along the shortest path to hers, indexed n. 
    Now Tom wants to block some of the roads so that Jerry has to walk longer to reach his girl's home, and he found that the cost of blocking a road equals to its length. Now he wants to know the minimum total cost to make Jerry walk longer.
    Note, if Jerry can't reach his girl's house in the very beginning, the answer is obviously zero. And you don't need to guarantee that there still exists a way from Jerry's house to his girl's after blocking some edges.

     

    Input

    The input begins with a line containing one integer T(1≤T≤10), the number of test cases.
    Each test case starts with a line containing two numbers n,m(1≤n,m≤10000), the number of houses and the number of one-way roads in the neighbourhood.
    m lines follow, each of which consists of three integers x,y,c(1≤x,y≤n,1≤c≤109), denoting that there exists a one-way road from the house indexed x to y of length c.

     

    Output

    Print T lines, each line containing a integer, the answer.

     

    Sample Input

    
     

    1 3 4 1 2 1 2 3 1 1 3 2 1 3 3

     

    Sample Output

    
     

    3

     

    Source

    2019 Multi-University Training Contest 1

     这题裸中裸

    太久没手撕最短路和网络流了

    写了好久 

    #include<bits/stdc++.h>
    using namespace std;
    
    long long first[10005];
    long long nxt[20005];
    long long from[20005];
    long long to[20005];
    long long wi[20005];
    long long vis[10005];
    long long havev[20005];
    long long cnt=0;
    long long ccnt=-1;
    long long  ffirst[10005];
    long long  fnxt[20005];
    long long fto[20005];
    
    long long cfirst[10005];//网络流数组
    long long cnxt[20005];
    long long cto[20005];
    long long cf[20005];
    long long cc[20005];
    long long n,m;
    
    void add(long long u,long long v,long long w)// 加一个正边一个反边
    {
        cnt++;
        from[cnt]=u;
        nxt[cnt]=first[u];
        first[u]=cnt;
        to[cnt]=v;
        wi[cnt]=w;
    
        fnxt[cnt]=ffirst[v];
        ffirst[v]=cnt;
        fto[cnt]=u;
    }
    
    void cadd(long long u,long long v,long long w)
    {
        ccnt++;
        cnxt[ccnt]=cfirst[u];
        cfirst[u]=ccnt;
        cc[ccnt]=w;
        cf[ccnt]=0;
        cto[ccnt]=v;
        ccnt++;
        cnxt[ccnt]=cfirst[v];
        cfirst[v]=ccnt;
        cc[ccnt]=0;
        cf[ccnt]=0;
        cto[ccnt]=u;
    }
    
    long long dis[10005];
    void spfa(long long x)
    {
        queue<int> q;
        q.push(1),vis[1]=1;
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        dis[1]=0;
        while(q.size())
        {
            long long tmp=q.front();
            q.pop(),vis[tmp]=0;
            for(long long i=first[tmp];i!=-1;i=nxt[i])
            {
                long long v=to[i];
                if(dis[tmp]+wi[i]<dis[v])
                {
                    dis[v]=dis[tmp]+wi[i];
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    
    const long long INF = 0x7fffffff;
    long long level[10005];
    
    bool dinic_bfs()      //bfs方法构造层次网络
    {
        //cout<<"level"<<endl;
        queue<int> q;
        memset(level, 0, sizeof(level));//每次全都重新分层
        q.push(1);//把源点推入初始点
        level[1] = 1;
        long long u, v;
        while (!q.empty())
        {
            u = q.front();
            q.pop();
            for (long long i=cfirst[u];i!=-1;i=cnxt[i])
            {
                v=cto[i];
                if (!level[v] && cc[i]>cf[i])
                {
                    level[v] = level[u] + 1;
                    q.push(v);
                }
            }
        }
        return level[n] != 0;                //question: so it must let the sink node is the Mth?/the way of yj is give the sink node's id
    }
    
    long long dinic_dfs(long long u, long long cp)             //use dfs to augment the flow
    {
        long long tmp = cp;
        long long v, t;
        if (u == n)
            return cp;
        for (long long i=cfirst[u];i!=-1&&tmp;i=cnxt[i])
        {
            v=cto[i];
            if (level[u] + 1 == level[v])
            {
                if (cc[i]>cf[i])
                {
                   // cout<<u<<" "<<v<<cc[i]<<" "<<
                    t = dinic_dfs(v, min(tmp, cc[i]-cf[i]));
                    cf[i] += t;
                    cf[i^1] -= t;
                    tmp -= t;
                }
            }
        }
        return cp - tmp;
    }
    
    long long dinic()
    {
        long long sum=0, tf=0;
        while (dinic_bfs())
        {
            while (tf = dinic_dfs(1, INF))
                sum += tf;
        }
        return sum;
    }
    
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        long long t;
        scanf("%lld",&t);
        while(t--)
        {
            cnt=0;
            ccnt=-1;
            memset(havev,0,sizeof(havev));
            memset(first,-1,sizeof(first));
            memset(cfirst,-1,sizeof(cfirst));
            memset(ffirst,-1,sizeof(ffirst));
            scanf("%lld%lld",&n,&m);
            for(long long i=1;i<=m;i++)
            {
                long long tmp1,tmp2,tmp3;
                scanf("%lld%lld%lld",&tmp1,&tmp2,&tmp3);
                add(tmp1,tmp2,tmp3);
            }
            spfa(1);
            //cout<<"disn"<<dis[n]<<endl;
            for(long long i=1;i<=cnt;i++)
            {
                for(long long j=first[i];j!=-1;j=nxt[j])
                {
                    if(dis[from[j]]==dis[to[j]]-wi[j])
                    cadd(from[j],to[j],wi[j]);
                    //cout<<from[i]<<" "<<to[i]<<" "<<wi[i]<<endl;
                }
            }
            long long ans=dinic();
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    hdu 5224 Tom and paper 水题
    2015 UESTC 搜索专题N题 韩爷的梦 hash
    2015 UESTC 搜索专题M题 Palindromic String 马拉车算法
    2015 UESTC 搜索专题K题 秋实大哥の恋爱物语 kmp
    2015 UESTC 搜索专题J题 全都是秋实大哥 kmp
    2015 UESTC 搜索专题F题 Eight Puzzle 爆搜
    2015 UESTC 搜索专题E题 吴队长征婚 爆搜
    2015 UESTC 搜索专题D题 基爷的中位数 二分
    2015 UESTC 搜索专题C题 基爷与加法等式 爆搜DFS
    2015 UESTC 搜索专题B题 邱老师降临小行星 记忆化搜索
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852240.html
Copyright © 2011-2022 走看看