• BZOJ 3931: [CQOI2015]网络吞吐量 最大流


    3931: [CQOI2015]网络吞吐量

    Time Limit: 1 Sec  

    Memory Limit: 256 MB

    题目连接

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

    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

    题意

    题解:

    跑最短路之后拆点,拆点来维护每个点最大扔出去的网络吞吐量

    然后直接搞就好了……

    这道题要爆int = =!

    怒wa一发

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <bitset>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 110000
    #define mod 10007
    #define eps 1e-9
    int Num;
    //const int inf=0x7fffffff;   //§ß§é§à§é¨f§³
    const ll Inf=0x3f3f3f3f3f3f3f3fll;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //**************************************************************************************
    namespace NetFlow
    {
        const ll MAXN=100000,MAXM=1000000,inf=0x3f3f3f3f3f3f3f3fll;
        struct Edge
        {
            ll v,c,f,nx;
            Edge() {}
            Edge(ll v,ll c,ll f,ll nx):v(v),c(c),f(f),nx(nx) {}
        } E[MAXM];
        ll G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
        void init(ll _n)
        {
            N=_n,sz=0; memset(G,-1,sizeof(G[0])*N);
        }
        void link(ll u,ll v,ll c)
        {
            E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
            E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
        }
        bool bfs(int S,int T)
        {
            static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N);
            dis[S]=0; Q[0]=S;
            for (int h=0,t=1,u,v,it;h<t;++h)
            {
                for (u=Q[h],it=G[u];~it;it=E[it].nx)
                {
                    if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                    {
                        dis[v]=dis[u]+1; Q[t++]=v;
                    }
                }
            }
            return dis[T]!=-1;
        }
        ll dfs(ll u,ll T,ll low)
        {
            if (u==T) return low;
            ll ret=0,tmp,v;
            for (ll &it=cur[u];~it&&ret<low;it=E[it].nx)
            {
                if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
                {
                    if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                    {
                        ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp;
                    }
                }
            }
            if (!ret) dis[u]=-1; return ret;
        }
        ll dinic(int S,int T)
        {
            ll maxflow=0,tmp;
            while (bfs(S,T))
            {
                memcpy(cur,G,sizeof(G[0])*N);
                while (tmp=dfs(S,T,inf)) maxflow+=tmp;
            }
            return maxflow;
        }
    }
    using namespace NetFlow;
    
    int n,m;
    struct node
    {
        ll x,y;
    };
    vector<node> EE[maxn];
    ll d[maxn];
    ll inq[maxn];
    ll cost[maxn];
    struct EEdge
    {
        ll x,y,z;
    };
    EEdge edge[maxn];
    vector<ll> U,V;
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=m;i++)
        {
            edge[i].x=read(),edge[i].y=read(),edge[i].z=read();
            EE[edge[i].x].push_back((node){edge[i].y,edge[i].z});
            EE[edge[i].y].push_back((node){edge[i].x,edge[i].z});
        }
        for(int i=0;i<=n;i++)
            d[i]=Inf;
        queue<int> Q;
        Q.push(1);
        d[1]=0;
        inq[1]=1;
        while(!Q.empty())
        {
            int u = Q.front();
            Q.pop();
            inq[u]=0;
            for(int i=0;i<EE[u].size();i++)
            {
                node v = EE[u][i];
                if(v.y+d[u]<d[v.x])
                {
                    d[v.x]=v.y+d[u];
                    if(!inq[v.x])
                    {
                        Q.push(v.x);
                        inq[v.x]=1;
                    }
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<EE[i].size();j++)
            {
                node v = EE[i][j];
                if(d[i]+v.y==d[v.x])
                    U.push_back(i+n),V.push_back(v.x);
            }
        }
        init(100000);
        for(int i=1;i<=n;i++)
        {
            cost[i]=read();
            if(i!=1&&i!=n)
                link(i,i+n,cost[i]);
            else
                link(i,i+n,inf);
        }
        for(int i=0;i<V.size();i++)
            link(U[i],V[i],inf);
        printf("%lld
    ",dinic(1,2*n));
    }
  • 相关阅读:
    java数据结构——哈希表(HashTable)
    java数据结构——红黑树(R-B Tree)
    java数据结构——二叉树(BinaryTree)
    java数据结构——递归(Recursion)例题持续更新中
    电路布线
    Cordova 入门
    mysql 分组加行号
    数据库表添加行号
    java jsp自定义标签
    java web Listener的简单使用案例
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4775753.html
Copyright © 2020-2023  润新知