zoukankan      html  css  js  c++  java
  • BZOJ3931 CQOI2015 网络吞吐量

    3931: [CQOI2015]网络吞吐量

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 2083  Solved: 870
    [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

    Source

    先跑出最短路,然后依据条件建图即可,最后跑出最大流即可

    #include <bits/stdc++.h>
    #define ll long long
    #define inf 1000000000007
    using namespace std;
    inline int read(){
        int x=0;int 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;
    }
    const int MAXN=2e5+10;
    struct node{
        int x,y,next;
        ll v;
    }e[MAXN<<1];
    int linkk[MAXN<<1],len=0,n,m,dis[MAXN],vis[MAXN],a[MAXN],b[MAXN],d[MAXN],qq[MAXN],head,tail,level[2000];
    typedef pair <int,int> pii;
    priority_queue < pii,vector<pii>,greater<pii> > q; 
    inline void insert(int xx,int yy,ll vv){
        e[++len].y=yy;e[len].v=vv;e[len].next=linkk[xx];linkk[xx]=len;
    }
    void dijsktra(){
        memset(dis,127,sizeof(dis));
        q.push(make_pair(0,1));
        dis[1]=0;
        while(!q.empty()){
            int tn=q.top().second;q.pop();
            if(vis[tn]) continue;
            vis[tn]=1;
            for(int i=linkk[tn];i;i=e[i].next){
                if(dis[tn]+e[i].v<dis[e[i].y]){
                    dis[e[i].y]=dis[tn]+e[i].v;
                    q.push(make_pair(dis[e[i].y],e[i].y));
                }
            }
        }
    }
    namespace zhangenming{
        inline bool getlevel(){
            memset(level,-1,sizeof(level));
            head=tail=0;
            qq[++tail]=1;level[1]=0;
            while(head<tail){
                int tn=qq[++head];
                for(int i=linkk[tn];i;i=e[i].next){
                    if(level[e[i].y]==-1&&e[i].v){    
                        level[e[i].y]=level[tn]+1;
                        qq[++tail]=e[i].y;
                    }
                }
            }
            return level[2*n]!=-1;
        }
        inline ll getmaxflow(int st,ll flow){
            if(st==2*n) return flow;
            ll d,maxflow=0;
            for(int i=linkk[st];i&&maxflow<flow;i=e[i].next){
                if(level[e[i].y]==level[st]+1&&e[i].v>0){
                    d=getmaxflow(e[i].y,min(e[i].v,flow-maxflow));
                    e[i].v-=d;
                    if(i%2==0) e[i-1].v+=d;
                    else e[i+1].v+=d;
                    maxflow+=d;
                }
            }
            if(!maxflow) level[st]=-1;
            return maxflow;
        }
        int dinic(){
            ll ans=0;ll sum;
            while(getlevel()){
                sum=getmaxflow(1,inf); ans+=sum;
            }
            cout<<ans<<endl;
        }
        void init(){
            n=read();m=read();
            for(int i=1;i<=m;i++){
                a[i]=read();b[i]=read();d[i]=read();
                insert(a[i],b[i],d[i]);
                insert(b[i],a[i],d[i]);
            }
            dijsktra();
            len=0;
            memset(linkk,0,sizeof(linkk));
            for(int i=1;i<=m;i++){
                if(dis[a[i]]+d[i]==dis[b[i]]) insert(a[i]+n,b[i],inf),insert(b[i],a[i]+n,0);
                if(dis[b[i]]+d[i]==dis[a[i]]) insert(b[i]+n,a[i],inf),insert(a[i],b[i]+n,0);
            }
            for(int i=1;i<=n;i++){
                int vv=read();
                if(i!=1&&i!=n) insert(i,i+n,vv);
                else insert(i,i+n,inf);
                insert(i+n,i,0);
            }
            dinic();
        }
    }
    int main(){
        using namespace zhangenming;
        init();
        return 0;
    }
    

      

  • 相关阅读:
    洗礼灵魂,修炼python(48)--巩固篇—模块
    洗礼灵魂,修炼python(48)--巩固篇—模块
    洗礼灵魂,修炼python(48)--巩固篇—模块
    Excel中拆分列
    Excel中拆分列
    Excel中拆分列
    Excel中拆分列
    Eclipse新建类的时候如何自动添加注释(作者,时间,版本等信息)
    Eclipse新建类的时候如何自动添加注释(作者,时间,版本等信息)
    用golang实现DDOS攻击网站
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/8029887.html
Copyright © 2011-2022 走看看