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

    3931: [CQOI2015]网络吞吐量

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

    Solution:

    先跑最短路

    拆点,每个点拆成两个点

    对于dis[i]+e(i,j)==dis[j]的边,我们连i'到j容量为INF的边

    对于i到i' 我们连c[i]的边(1和n除外)

    最后跑dinic即是

    正确性:我们可以认为先是x的流到了某个点然后被滤掉了某些流量

    /*To The End Of The Galaxy*/
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<iomanip>
    #include<stack>
    #include<map>
    #include<set>
    #include<cmath>
    #include<complex>
    #define debug(x) cerr<<#x<<"="<<x<<endl
    #define INF 0x7f7f7f7f
    #define llINF 0x7fffffffffffll
    using namespace std;
    typedef pair<int,int> pii;
    typedef long long ll;
    inline int init()
    {
        int now=0,ju=1;char c;bool flag=false;
        while(1)
        {
            c=getchar();
            if(c=='-')ju=-1;
            else if(c>='0'&&c<='9')
            {
                now=now*10+c-'0';
                flag=true;
            }
            else if(flag)return now*ju;
        }
    }
    inline long long llinit()
    {
        long long now=0,ju=1;char c;bool flag=false;
        while(1)
        {
            c=getchar();
            if(c=='-')ju=-1;
            else if(c>='0'&&c<='9')
            {
                now=now*10+c-'0';
                flag=true;
            }
            else if(flag)return now*ju;
        }
    }
    int head[1505];
    ll dis[1505];
    bool vis[1505];
    int cnt=0;
    struct road
    {
        int from,to;
        ll val;int pre;
    }e[200005];
    struct edge
    {
        int from,to;
        ll cap,flow;
        int pre;
    }Edge[2000005];
    inline void insert(int from,int to,ll val)
    {
        ++cnt;
        e[cnt]=((road){from,to,val,head[from]});
        head[from]=cnt;
    }
    inline void addedge(int from,int to,ll cap)
    {
        ++cnt;
        Edge[cnt]=((edge){from,to,cap,0,head[from]});
        head[from]=cnt;
        ++cnt;
        Edge[cnt]=((edge){to,from,0,0,head[to]});
        head[to]=cnt;
    }
    int S=1,T,n,m;
    priority_queue<pii,vector<pii>,greater<pii> > q;
    inline void dijkstra()
    {
        pii now;
        for(int i=1;i<=n;i++)
        {
            dis[i]=llINF;
            vis[i]=0;
        }
        dis[1]=0;
        q.push(make_pair(0,1));
        while(!q.empty())
        {
            now=q.top();q.pop();
            if(vis[now.second])continue;
            vis[now.second]=1;
            for(int j=head[now.second];j;j=e[j].pre)
            {
                if(!vis[e[j].to]&&dis[e[j].to]>dis[now.second]+e[j].val)
                {
                    dis[e[j].to]=dis[now.second]+e[j].val;
                    q.push(make_pair(dis[e[j].to],e[j].to));
                }
            }
        }
    }
    int v[1505],cur[1505];
    queue<int> Q;
    bool bfs()
    {
        int now;
        while(!Q.empty())Q.pop();
        for(int i=S;i<=T;i++)
        {
            dis[i]=INF;
            vis[i]=0;
        }
        dis[1]=1;
        Q.push(1);
        while(!Q.empty())
        {
            now=Q.front();Q.pop();
            if(now==T)return true;
            if(vis[now])continue;
            vis[now]=1;
            for(int j=head[now];j;j=Edge[j].pre)
            {
                if(!vis[Edge[j].to]&&Edge[j].cap>Edge[j].flow)
                {
                    dis[Edge[j].to]=dis[now]+1;
                    Q.push(Edge[j].to);
                }
            }
        }
        return false;
    }
    ll dfs(int now,ll maxflow)
    {
        if(now==T||maxflow==0)return maxflow;
        int &j=cur[now];
        ll flow=0,f;
        for(;j;j=Edge[j].pre)
        {
            if(dis[Edge[j].to]==dis[now]+1&&(f=dfs(Edge[j].to,min(maxflow,Edge[j].cap-Edge[j].flow)))>0)
            {
                flow+=f;maxflow-=f;
                Edge[j].flow+=f;Edge[((j-1)^1)+1].flow-=f;
                if(maxflow==0)break;
            }
        }
        return flow;
    }
    ll dinic()
    {
        ll ans=0;
        while(bfs())
        {
            for(int i=S;i<=T;i++)cur[i]=head[i];
            ans+=dfs(S,llINF);
        }
        return ans;
    }
    int main()
    {
        int a,b,c;
        n=init();m=init();
        T=2*n;
        for(int i=1;i<=m;i++)
        {
            a=init();b=init();c=init();
            insert(a,b,c);
            insert(b,a,c);
        }
        for(int i=1;i<=n;i++)
        {
            v[i]=init();
        }
        dijkstra();
        cnt=0;
        memset(head,0,sizeof(head));
        for(int i=1;i<=n;i++)
        {
            if(i==1||i==n)addedge(i,i+n,llINF);
            else addedge(i,i+n,v[i]);
        }
        for(int i=1;i<=2*m;i++)
        {
            if(dis[e[i].to]==dis[e[i].from]+e[i].val)
            {
                addedge(e[i].from+n,e[i].to,llINF);
            }
        }
        printf("%lld
    ",dinic());
        return 0;
    }
    View Code
  • 相关阅读:
    左偏树
    论在Windows下远程连接Ubuntu
    ZOJ 3711 Give Me Your Hand
    SGU 495. Kids and Prizes
    POJ 2151 Check the difficulty of problems
    CodeForces 148D. Bag of mice
    HDU 3631 Shortest Path
    HDU 1869 六度分离
    HDU 2544 最短路
    HDU 3584 Cube
  • 原文地址:https://www.cnblogs.com/redwind/p/6501594.html
Copyright © 2011-2022 走看看