您的位置:首页 > 理论基础 > 计算机网络

【BZOJ】【3931】【CQOI2015】网络吞吐量

2015-06-17 18:00 579 查看

最短路+最大流

  思维难度并不高,其实题面几乎已经把算法讲完了……

  练习模板的好题= =

  哦对了,求最短路和最大流的时候都得开long long……QwQ

/**************************************************************
Problem: 3931
User: Tunix
Language: C++
Result: Accepted
Time:316 ms
Memory:12256 kb
****************************************************************/

//BZOJ 3931
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline int getint(){
int v=0,sign=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
return v*sign;
}
const int N=1010,M=200010;
const LL INF=1e15;
/******************tamplate*********************/

int head
,to[M<<1],nxt[M<<1],l[M<<1],cnt;
typedef long long LL;
void add(int x,int y,int z){
to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt; l[cnt]=z;
to[++cnt]=x; nxt[cnt]=head[y]; head[y]=cnt; l[cnt]=z;
}
int n,m,a
,vis
,tot;
LL ans,dis
,c
;

void Dij();
struct edge{int to;LL v;};
struct Net{
edge E[M<<1];
int head
,nxt[M<<1],cnt;
void ins(int x,int y,LL z){
E[++cnt]=(edge){y,z}; nxt[cnt]=head[x]; head[x]=cnt;
}
void add(int x,int y,LL z){
ins(x,y,z); ins(y,x,0);
}
int S,T,d
,cur
;
queue<int>Q;
bool mklevel(){
memset(d,-1,sizeof d);
d[S]=0;
Q.push(S);
while(!Q.empty()){
int x=Q.front(); Q.pop();
for(int i=head[x];i;i=nxt[i])
if (d[E[i].to]==-1 && E[i].v){
d[E[i].to]=d[x]+1;
Q.push(E[i].to);
}
}
return d[T]!=-1;
}
int dfs(int x,LL a){
if (x==T) return a;
LL flow=0;
for(int &i=cur[x];i && flow<a;i=nxt[i])
if (d[E[i].to]==d[x]+1 && E[i].v){
LL f=dfs(E[i].to,min(E[i].v,a-flow));
E[i].v-=f;
E[i^1].v+=f;
flow+=f;
}
if (!flow) d[x]=-1;
return flow;
}
void Dinic(){
while(mklevel()){
F(i,0,T) cur[i]=head[i];
ans+=dfs(S,INF);
}
}
void init(){
S=0,T=n*2+1; cnt=1;
Dij();
F(i,1,n) add(i,n+i,c[i]);
add(S,1,INF); add(n+n,T,INF);
Dinic();
printf("%lld\n",ans);
}
}G1;
typedef pair<int,int> pii;
#define mp make_pair
#define fi first
#define se second

priority_queue<pii,vector<pii>,greater<pii> >Q;
void Dij(){
memset(dis,0x3f,sizeof dis);
dis[1]=0;
Q.push(mp(0,1));
while(!Q.empty()){
int x=Q.top().se; Q.pop();
if (vis[x]) continue;
vis[x]=++tot;
a[tot]=x;
for(int i=head[x];i;i=nxt[i])
if (dis[to[i]]>dis[x]+l[i]){
dis[to[i]]=dis[x]+l[i];
Q.push(mp(dis[to[i]],to[i]));
}
}
F(x,1,n)
for(int i=head[x];i;i=nxt[i])
if (dis[to[i]]==dis[x]+l[i])
G1.add(x+n,to[i],INF);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("3931.in","r",stdin);
freopen("3931.out","w",stdout);
#endif
n=getint(); m=getint();
F(i,1,m){
int x=getint(),y=getint(),z=getint();
add(x,y,z);
}
F(i,1,n) c[i]=getint();
c[1]=c
=INF;
G1.init();
return 0;
}


View Code

3931: [CQOI2015]网络吞吐量

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

[Submit][Status][Discuss]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: