bzoj3931: [CQOI2015]网络吞吐量
http://www.lydsy.com/JudgeOnline/problem.php?id=3931
在最短路网络上跑最大流
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; const LL inf=1e16; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } struct NetworkFlow { #define N 1100 #define M 260000 int tot; int front[N],nxt[M<<1],to[M<<1],from[M<<1]; LL val[M<<1]; int lev[N],num[N]; int path[N]; int cur[N]; int src,decc; int cap[501]; /*int se[501]; int edge[501][501];*/ void add(int u,int v,LL w) { to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; from[tot]=u; val[tot]=w; to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; from[tot]=v; val[tot]=0; } bool bfs() { queue<int>q; for(int i=src;i<=decc;++i) lev[i]=decc-src+1; q.push(decc); lev[decc]=0; int now,t; while(!q.empty()) { now=q.front(); q.pop(); for(int i=front[now];i;i=nxt[i]) { t=to[i]; if(lev[t]==decc-src+1 && val[i^1]) { lev[t]=lev[now]+1; q.push(t); } } } return lev[src]!=decc-src+1; } int augment() { int now=decc; LL flow=inf; int i; while(now!=src) { i=path[now]; flow=min(flow,val[i]); now=from[i]; } now=decc; while(now!=src) { i=path[now]; val[i]-=flow; val[i^1]+=flow; now=from[i]; } return flow; } LL isap() { LL flow=0; if(!bfs()) return 0; memset(num,0,sizeof(num)); for(int i=src;i<=decc;++i) num[lev[i]]++,cur[i]=front[i]; int now=src,t; while(lev[src]<=decc-src) { if(now==decc) { flow+=augment(); now=src; } bool advanced=false; for(int i=cur[now];i;i=nxt[i]) { t=to[i]; if(lev[t]==lev[now]-1 && val[i]) { advanced=true; path[t]=i; cur[now]=i; now=t; break; } } if(!advanced) { int mi=decc; for(int i=front[now];i;i=nxt[i]) if(val[i]) mi=min(mi,lev[to[i]]); if(!--num[lev[now]]) break; num[lev[now]=mi+1]++; cur[now]=front[now]; if(now!=src) now=from[path[now]]; } } return flow; } void build(int n) { //for(int i=1;i<=n;++i) cout<<se[i]<<'\n'; src=3; decc=n<<1; for(int i=2;i<n;++i) add(i<<1,i<<1|1,cap[i]); /*for(int i=1;i<=n;++i) { for(int j=1;j<=se[i];++j) add(i<<1|1,edge[i][j]<<1,inf); }*/ } #undef N #undef M }Net; struct Graph { #define N 501 #define M 100001 int tot; int front[N],to[M<<1],nxt[M<<1],val[M<<1],from[M<<1]; LL DIS[N]; bool vis[N]; struct node { LL dis; int id; bool operator < (node p) const { return dis>p.dis; } }cur,nt; void add(int u,int v,int w) { to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w; from[tot]=u; to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=w; from[tot]=v; } void dijkstra(int n) { memset(DIS,1,sizeof(DIS)); DIS[n]=0; priority_queue<node>q; cur.dis=0; cur.id=n; q.push(cur); while(!q.empty()) { cur=q.top(); q.pop(); if(DIS[cur.id]!=cur.dis) continue; for(int i=front[cur.id];i;i=nxt[i]) { if(DIS[to[i]]>DIS[cur.id]+val[i]) { DIS[to[i]]=DIS[cur.id]+val[i]; nt.dis=DIS[to[i]]; nt.id=to[i]; q.push(nt); } } } } void build() { Net.tot=1; for(int i=1;i<=tot;++i) { if(DIS[from[i]]-val[i]==DIS[to[i]]) { //cout<<from[i]<<' '<<to[i]<<'\n'; Net.add(from[i]<<1|1,to[i]<<1,inf); } } } #undef N #undef M }G; int main() { //freopen("cqoi15_network.in","r",stdin); //freopen("cqoi15_network.out","w",stdout); int n,m; read(n); read(m); int u,v,w; while(m--) { read(u); read(v); read(w); G.add(u,v,w); } for(int i=1;i<=n;++i) read(Net.cap[i]); G.dijkstra(n); //cout<<G.DIS[1]<<'\n'; G.build(); Net.build(n); cout<<Net.isap(); }
3931: [CQOI2015]网络吞吐量
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2094 Solved: 873
[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
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