zoukankan      html  css  js  c++  java
  • bzoj3931: [CQOI2015]网络吞吐量

    http://www.lydsy.com/JudgeOnline/problem.php?id=3931

    在最短路网络上跑最大流

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    const LL inf=1e16;
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c))  c=getchar(); 
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar();  }
    }
    
    struct NetworkFlow
    {
        #define N 1100
        #define M 260000
        
        int tot;
        int front[N],nxt[M<<1],to[M<<1],from[M<<1];
        LL val[M<<1];
        
        int lev[N],num[N];
        int path[N];
        int cur[N];
         
        int src,decc;
        
        int cap[501];
        
        /*int se[501];
        int edge[501][501];*/
        
        void add(int u,int v,LL w)
        {
            to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; from[tot]=u; val[tot]=w;
            to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; from[tot]=v; val[tot]=0;
        }
        
        bool bfs()
        {
            queue<int>q;
            for(int i=src;i<=decc;++i) lev[i]=decc-src+1;
            q.push(decc);
            lev[decc]=0;
            int now,t;
            while(!q.empty())
            {
                now=q.front();
                q.pop();
                for(int i=front[now];i;i=nxt[i])
                {
                    t=to[i];
                    if(lev[t]==decc-src+1 && val[i^1]) 
                    {
                        lev[t]=lev[now]+1;
                        q.push(t);
                    }
                }
            }
            return lev[src]!=decc-src+1;
        }
         
        int augment()
        {
            int now=decc;
            LL flow=inf;
            int i;
            while(now!=src)
            {
                i=path[now];
                flow=min(flow,val[i]);
                now=from[i];
            }
            now=decc;
            while(now!=src)
            {
                i=path[now];
                val[i]-=flow;
                val[i^1]+=flow;
                now=from[i];
            }
            return flow;
        }
         
        LL isap()
        {
            LL flow=0;
            if(!bfs()) return 0;
            memset(num,0,sizeof(num));
            for(int i=src;i<=decc;++i) num[lev[i]]++,cur[i]=front[i];
            int now=src,t;
            while(lev[src]<=decc-src)
            {
                if(now==decc)
                {
                    flow+=augment();
                    now=src;
                }
                bool advanced=false;
                for(int i=cur[now];i;i=nxt[i])
                {
                    t=to[i];
                    if(lev[t]==lev[now]-1 && val[i])
                    {
                        advanced=true;
                        path[t]=i;
                        cur[now]=i;
                        now=t;
                        break;
                    }
                }
                if(!advanced)
                {
                    int mi=decc;
                    for(int i=front[now];i;i=nxt[i])
                        if(val[i]) mi=min(mi,lev[to[i]]);
                    if(!--num[lev[now]]) break;
                    num[lev[now]=mi+1]++;
                    cur[now]=front[now];
                    if(now!=src) now=from[path[now]];
                }
            }
            return flow;
        }
        
        void build(int n)
        {
            //for(int i=1;i<=n;++i) cout<<se[i]<<'
    ';
            src=3;
            decc=n<<1;
            for(int i=2;i<n;++i) add(i<<1,i<<1|1,cap[i]);
            /*for(int i=1;i<=n;++i)
            {
                for(int j=1;j<=se[i];++j)
                    add(i<<1|1,edge[i][j]<<1,inf);
            }*/
        }
        
        #undef N
        #undef M
    
    }Net;
    
    struct Graph
    {
        #define N 501
        #define M 100001
        
        int tot;
        int front[N],to[M<<1],nxt[M<<1],val[M<<1],from[M<<1];
        
        LL DIS[N];
        
        bool vis[N];
        
        struct node
        {
            LL dis;
            int id;
            bool operator < (node p) const
            {
                return dis>p.dis;
            }
        }cur,nt;
        
        void add(int u,int v,int w)
        {
            to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w; from[tot]=u;
            to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=w; from[tot]=v;
        }
        
        void dijkstra(int n)
        {
            memset(DIS,1,sizeof(DIS));
            DIS[n]=0;
            priority_queue<node>q;
            cur.dis=0;
            cur.id=n;
            q.push(cur);
            while(!q.empty())
            {
                cur=q.top();
                q.pop();
                if(DIS[cur.id]!=cur.dis) continue;
                for(int i=front[cur.id];i;i=nxt[i])
                {
                    if(DIS[to[i]]>DIS[cur.id]+val[i])
                    {
                        DIS[to[i]]=DIS[cur.id]+val[i];
                        nt.dis=DIS[to[i]];
                        nt.id=to[i];
                        q.push(nt);
                    }
                }
            }
        }
        
        void build()
        {
            Net.tot=1;
            for(int i=1;i<=tot;++i)
            {
                if(DIS[from[i]]-val[i]==DIS[to[i]]) 
                {
                    //cout<<from[i]<<' '<<to[i]<<'
    ';
                    Net.add(from[i]<<1|1,to[i]<<1,inf);
                }
            }
        }
        
        #undef N
        #undef M
    }G;
    
    int main()
    {
        //freopen("cqoi15_network.in","r",stdin);
        //freopen("cqoi15_network.out","w",stdout);
        int n,m;
        read(n); read(m);
        int u,v,w;
        while(m--)
        {
            read(u); read(v); read(w);
            G.add(u,v,w);
        }
        for(int i=1;i<=n;++i) read(Net.cap[i]);
        G.dijkstra(n);
        //cout<<G.DIS[1]<<'
    ';
        G.build();
        Net.build(n);
        cout<<Net.isap();
    }

    3931: [CQOI2015]网络吞吐量

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 2094  Solved: 873
    [Submit][Status][Discuss]

    Description

     路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点。网络中实现路由转发的硬件设备称为路由器。为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包。例如在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包。现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数量),假设所有数据包一定沿最短路径转发,试计算从路由器1到路由器n的网络的最大吞吐量。计算中忽略转发及传输的时间开销,不考虑链路的带宽限制,即认为数据包可以瞬间通过网络。路由器1到路由器n作为起点和终点,自身的吞吐量不用考虑,网络上也不存在将1和n直接相连的链路。

     

    Input

    输入文件第一行包含两个空格分开的正整数n和m,分别表示路由器数量和链路的数量。网络中的路由器使用1到n编号。接下来m行,每行包含三个空格分开的正整数a、b和d,表示从路由器a到路由器b存在一条距离为d的双向链路。 接下来n行,每行包含一个正整数c,分别给出每一个路由器的吞吐量。

     

    Output

    输出一个整数,为题目所求吞吐量。

     

    Sample Input

    7 10
    1 2 2
    1 5 2
    2 4 1
    2 3 3
    3 7 1
    4 5 4
    4 3 1
    4 6 1
    5 6 2
    6 7 1
    1
    100
    20
    50
    20
    60
    1

    Sample Output

    70

    HINT

     对于100%的数据,n≤500,m≤100000,d,c≤10^9

  • 相关阅读:
    学指令 emacs篇
    c 排序 总结
    C# WinForm源码下载
    PetShop下载
    Visual Studio常用技巧
    人事信息管理系统(PMS)
    css实现细表格原理
    GridView导出Excel/Word
    dotnet程序员装机必备工具
    容器练习一
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8039954.html
Copyright © 2011-2022 走看看