【BZOJ-3931】网络吞吐量 最短路 + 最大流

3931: [CQOI2015]网络吞吐量

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

傻逼题,卡我!

跟着题意走,先求最短路,然后利用最短路径建图跑最大流,简言之就是两个模板

PS自己的Code在BZOJ上被卡T了但COGS上跑的飞快,于是直接黏贴黄学长的

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int read()
{
    int 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;
}
#define maxn 1000
#define maxm 1000010
int n,m;
struct EdgeNode{int to,next;long long cap;}edge[maxm];
struct RoadNode{int to,next,len;}road[maxn<<1];
int head[maxn<<1],cnt=1,last[maxn],tot;
void addroad(int u,int v,int w) {tot++; road[tot].to=v; road[tot].next=last[u]; last[u]=tot; road[tot].len=w;}
void insertroad(int u,int v,int w) {addroad(u,v,w); addroad(v,u,w);}
void addedge(int u,int v,long long w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].cap=w;}
void insertedge(int u,int v,long long w) {addedge(u,v,w); addedge(v,u,0);}
long long dis[maxn]; int s,t; bool visit[maxn];
#define inf 1000000000000000LL
void spfa()
{
    for (int i=s; i<=t; i++) dis[i]=inf;
    queue<int>q; q.push(s); visit[s]=1; dis[s]=0;
    while (!q.empty())
        {
            int now=q.front(); q.pop(); visit[now]=0;
            for (int i=last[now]; i; i=road[i].next)
                if (dis[road[i].to]>dis[now]+road[i].len)
                    {
                        dis[road[i].to]=(long long)(dis[now]+road[i].len);
                        if (!visit[road[i].to])
                            visit[road[i].to]=1,q.push(road[i].to);
                    }
        }
}
int h[maxn<<1],cur[maxn<<1],S,T;
bool bfs()
{
    queue<int>q;
    for (int i=S; i<=T; i++) h[i]=-1;
    q.push(S); h[S]=0;
    while (!q.empty())
        {
            int now=q.front(); q.pop();
            for (int i=head[now]; i; i=edge[i].next)
                if (edge[i].cap && h[edge[i].to]==-1)
                    h[edge[i].to]=h[now]+1,q.push(edge[i].to);
        }
    return h[T]!=-1;
}
long long dfs(int loc,long long low)
{
    if (loc==T) return low;
    long long w,used=0;
    for (int i=cur[loc]; i; i=edge[i].next)
        if (edge[i].cap && h[edge[i].to]==h[loc]+1)
            {
                w=dfs(edge[i].to,min(low-used,(long long)edge[i].cap));
                edge[i].cap-=w; edge[i^1].cap+=w; used+=w;
                if (used==low) return low; if (edge[i].cap) cur[loc]=i;
            }
    if (!used) dis[loc]=-1;
    return used;
}

long long dinic()
{
    long long tmp=0;
    while (bfs())
        {
            for (int i=S; i<=T; i++) cur[i]=head[i];
            tmp+=dfs(S,inf);
        }
    return tmp;
}
int tt[maxn],uu[maxm],vv[maxm],ww[maxm];
int main()
{
    freopen("cqoi15_network.in","r",stdin);
    freopen("cqoi15_network.out","w",stdout);
    n=read(),m=read();
    for (int i=1; i<=m; i++) uu[i]=read(),vv[i]=read(),ww[i]=read(),insertroad(uu[i],vv[i],ww[i]);
    s=1,t=n; spfa();
    for (int i=1; i<=n; i++) tt[i]=read();
    S=0; T=n*2+1;
    for (int i=2; i<=n-1; i++) insertedge(i,i+n,(long long)tt[i]);
    insertedge(S,1,inf); insertedge(1,1+n,inf); insertedge(n,n+n,inf); insertedge(n+n,T,inf);
    for (int i=1; i<=m; i++)
        {
            if (dis[uu[i]]+ww[i]==dis[vv[i]]) insertedge(uu[i]+n,vv[i],inf);
            if (dis[vv[i]]+ww[i]==dis[uu[i]]) insertedge(vv[i]+n,uu[i],inf);
        }
    printf("%lld\n",dinic());
    return 0;
}

BZOJ上精神AC,傻逼题爱咋咋地,反正读完题直接出正解,就这傻逼题,蛋爷当年能写一周?

COGS上效果图:

时间: 2024-10-18 20:52:18

【BZOJ-3931】网络吞吐量 最短路 + 最大流的相关文章

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

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

BZOJ 3931 CQOI 2015 网络吞吐量 最短路+最大流

题目大意 给出一个无向图,求出在这个图上1到n的所有最短路形成的图的最大流. 思路 想让大家叠模板也不带这么懒得吧.. 记得开long long就行了. CODE #define _CRT_SECURE_NO_WARNINGS #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAXP 100

【BZOJ3931】【CQOI2015】网络吞吐量 最短路+网络流

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44922137"); } 题解: --两遍最短路然后判断哪些边可以在某条最短路上,然后加到网络流图中. 然后题意是一个点经过流量有限制,拆点就好. 然后有重边Qwq(调了好久...) 然后或许有自环,不过这并不影响什么. 代码: 调试

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

题目描述 传送门 题解 求出最短路径图之后拆点跑最大流. 判断一条边在最短路图上:dis[edge[i].x]+redis[edge[i].y]+edge[i].w==dis[n]或dis[edge[i].y]+redis[edge[i].x]+edge[i].w==dis[n],其中dis和redis都是单源最短路,源分别为1和n 代码 #include<algorithm> #include<iostream> #include<cstring> #include&

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

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

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】网络吞吐量

最短路+最大流 思维难度并不高,其实题面几乎已经把算法讲完了…… 练习模板的好题= = 哦对了,求最短路和最大流的时候都得开long long……QwQ 1 /************************************************************** 2 Problem: 3931 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:316 ms 7 Memory:12256 kb 8 ********

BZOJ 3931: [CQOI2015]网络吞吐量

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

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

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