P3171 [CQOI2015]网络吞吐量

P3171 [CQOI2015]网络吞吐量https://www.luogu.org/problemnew/show/P3171

题目描述

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

输入格式:

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

输出格式:

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

输入样例:

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

输出样例:

70

说明

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


正解思路:最短路+最大流

1.跑出最短路[可能有多条] (貌似DJ比Spfa快??)

2.将所有最短路上的边连到网络流的图上[将u+n节点与v节点连边,容量为inf]

3.拆点,限制流量[将i节点与i+n节点连边,容量为节点的吞吐量] (1节点和n节点连边时的容量置为inf)

4.跑最大流

实现时的难点:
对于步骤2,可以枚举每一条边,如果有dist[u]+w==dist[v],则该边一定在一条最短路上[注意双向都要判断] (试过dfs,不好写,可以过样例,但是会TLE和RE)
实现时的坑点:
inf需要很大,1e9是不够的
#define RG register
#define LL long long
#define inf (1LL<<60)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int N=505,NN=2000,M=1e5+5;
inline LL read()
{
    RG LL x=0,w=1;RG char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
    return x*w;
}
inline LL minn(LL a,LL b){return a<b?a:b;}
LL n,m,S,T,Ans,cnt;//源点S为1,汇点T为2*n
LL last[N],dist[N];//last[]是跑最短路建图时所用的邻接表的末指针数组,dist[i]表示节点i到起点1的最短路长度
LL a[M],b[M],c[M];//存储边的信息
LL dep[NN],cur[NN],head[NN];//dep[]为dfs深度,cur[]当前弧,head[]是跑最大流建图时所用的邻接表的末指针数组
bool used[N];//用于跑Spfa
struct edge{
    LL to,next,w;
}e[2*M],ee[3*M];//两个图
inline void insert(LL u,LL v,LL w)//连边[最短路] (双向边)
{
    e[++cnt]=(edge){v,last[u],w};last[u]=cnt;
    e[++cnt]=(edge){u,last[v],w};last[v]=cnt;
}
inline void link(LL u,LL v,LL w)//连边[最大流] (单向边)
{
    ee[++cnt]=(edge){v,head[u],w};head[u]=cnt;
    ee[++cnt]=(edge){u,head[v],0};head[v]=cnt;
}
queue<LL> Q;
inline void Spfa()
{
    for(LL i=1;i<=n;i++)dist[i]=inf;
    dist[1]=0;
    used[1]=true;
    Q.push(1);
    while(!Q.empty())
    {
        LL now=Q.front();Q.pop();
        for(LL i=last[now];i;i=e[i].next)
        {
            LL v=e[i].to;
            if(dist[v]>dist[now]+e[i].w)
            {
                dist[v]=dist[now]+e[i].w;
                if(!used[v])Q.push(v),used[v]=1;
            }
        }
        used[now]=0;
    }
}
inline bool bfs()
{
    while(!Q.empty())Q.pop();
    memset(dep,0,sizeof(dep));
    dep[S]=1;
    Q.push(S);
    while(!Q.empty())
    {
        LL now=Q.front();Q.pop();
        for(LL i=head[now];i;i=ee[i].next)
        {
            LL v=ee[i].to;
            if(ee[i].w>0&&!dep[v])
            {
                dep[v]=dep[now]+1;
                Q.push(v);
            }
        }
    }
    return dep[T]!=0;
}
LL dfs(LL now,LL flow)
{
    if(now==T)return flow;
    for(LL& i=cur[now];i;i=ee[i].next)
    {
        LL v=ee[i].to;
        if(dep[v]==dep[now]+1&&ee[i].w!=0)
        {
            LL di=dfs(v,minn(flow,ee[i].w));
            if(di>0){ee[i].w-=di;ee[i^1].w+=di;return di;}
        }
    }
    return 0;
}
int main()
{
    n=read();
    m=read();
    for(LL i=1;i<=m;i++)
    {
        a[i]=read(),b[i]=read(),c[i]=read();
        insert(a[i],b[i],c[i]);
    }
    Spfa();
    cnt=1;
    for(LL i=1;i<=m;i++)//连边
    {
        if(dist[a[i]]+c[i]==dist[b[i]])link(a[i]+n,b[i],inf);
        if(dist[b[i]]+c[i]==dist[a[i]])link(b[i]+n,a[i],inf);
    }
    for(LL i=1;i<=n;i++)//拆点
    {
        LL x=read();
        if(i==1||i==n)link(i,i+n,inf);
        else link(i,i+n,x);
    }
    S=1;T=2*n;
    while(bfs())
    {
        for(LL i=S;i<=T;i++)cur[i]=head[i];
        while(LL d=dfs(S,inf))Ans+=d;
    }
    printf("%lld\n",Ans);
    return 0;
}

原文地址:https://www.cnblogs.com/sdzwyq/p/8456851.html

时间: 2024-10-10 12:59:31

P3171 [CQOI2015]网络吞吐量的相关文章

BZOJ 3931: [CQOI2015]网络吞吐量

3931: [CQOI2015]网络吞吐量 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1555  Solved: 637[Submit][Status][Discuss] Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短路径优先)中

BZOJ 3931: [CQOI2015]网络吞吐量( 最短路 + 最大流 )

最短路 + 最大流 , 没什么好说的... 因为long long WA 了两次.... ------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<iostre

bzoj3931: [CQOI2015]网络吞吐量

将最短路图找出来,跑maxflow即可.有注意到数据范围.然后输出的时候%dWA了三次QAQ... #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define ll long long #

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

3931: [CQOI2015]网络吞吐量 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=3931 Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短

bzoj 3931: [CQOI2015]网络吞吐量(最短路+网络流)

3931: [CQOI2015]网络吞吐量 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 1194  Solved: 508 [Submit][Status][Discuss] Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短路径优先

3931: [CQOI2015]网络吞吐量【网络流】

网络吞吐量(network)题目描述路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如,在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包.现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数量),假设所有数据包一定沿最

[BZOJ 3931][CQOI2015]网络吞吐量(SPFA+网络流)

Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包.现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数量),假设所有数据包一定沿最短路径转发,试

BZOJ3931 [CQOI2015]网络吞吐量(最大流)

没啥好说的,有写过类似的,就是预处理出最短路上的边建容量网络. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1LL<<60) 7 #define MAXN 1111 8 #define MAXM 1111*1111*2 9 10 struct Edge{ 11

bzoj 3931 [CQOI2015]网络吞吐量(最短路,最大流)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3931 [题意] 只能通过1-n的最短路,求网络最大流 [思路] 分别以1,n为起点做最短路,则可以判断一条边是否在最短路上. 以最短路构建网络,并且将一个点拆成两个中间连c[i]表示结点容量限制. [代码] 1 #include<set> 2 #include<cmath> 3 #include<queue> 4 #include<vector>