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\n",dinic(1,2*n));
}

 

    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/4775753.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞