列表

详情


NC19939. [CQOI2015]网络吞吐量

描述

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

输入描述

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

输出描述

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

示例1

输入:

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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 42ms, 内存消耗: 17132K, 提交时间: 2022-12-26 13:18:49

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 510 * 510, M = 5e5 + 10, INF = 0x3f3f3f3f3f3f3f3f;

int h[N], e[M], ne[M], f[M], idx, d[N], cur[N], n, m, S, T, a[N], dp[N], ans1, ans2, ans3;

void add(int a, int b, int c)
{
	e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
	e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}

bool bfs()
{
	queue<int>q;
	memset(d, -1, sizeof d);
	q.push(S);
	d[S] = 0;
	cur[S] = h[S];
	while(!q.empty())
	{
		auto t = q.front();
		q.pop();
		for(int i = h[t]; ~i; i = ne[i])
		{
			int j = e[i];
			if(d[j] == -1 && f[i])
			{
				d[j] = d[t] + 1;
				cur[j] = h[j];
				if(j == T) return true;
				q.push(j);
			}
		}
	}
	return false;
}

int find(int u, int limit)
{
	if(u == T) return limit;
	int flow = 0;
	for(int i = cur[u]; ~i && flow < limit; i = ne[i])
	{
		int j = e[i];
		if(d[j] == d[u] + 1 && f[i])
		{
			int t = find(j, min(f[i], limit - flow));
			if(!t) d[j] = -1;
			f[i] -= t, f[i ^ 1] += t, flow += t;
		}
	}
	return flow;
}

int dinic()
{
	int r = 0, flow;
	while(bfs()) while(flow = find(S, INF)) r += flow;
	return r;
}

typedef pair<int, int>PII;
vector<PII>g[N];
int dist[N];
bool st[N];

void dijkstra()
{
	priority_queue<PII, vector<PII>, greater<PII>>heap;
	memset(dist, 0x3f, sizeof dist);
	dist[1] = 0;
	heap.push({0, 1});

	while(!heap.empty())
	{
		auto t = heap.top();
		heap.pop();
		int ver = t.second;
		if(st[ver]) continue;
		st[ver] = true;
		for(auto t : g[ver])
		{
			int j = t.first, w = t.second;
			if(dist[j] > dist[ver] + w)
			{
				dist[j] = dist[ver] + w;
				heap.push({dist[j], j});
			}
		}
	}

	for(int i = 1; i <= n; i ++ )
		for(auto t : g[i])
		{
			int j = t.first, w = t.second;
			if(dist[j] == dist[i] + w)
				add(i + n, j, INF);
		}
}
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	memset(h, -1, sizeof h);
	cin >> n >> m;
	S = 0, T = 2 * n + 1;
	add(S, 1, INF), add(2 * n, T, INF);
	
	for(int i = 1; i <= m; i ++ )
	{
		int u, v, w;
		cin >> u >> v >> w;
		g[u].push_back({v, w}), g[v].push_back({u, w});
	}
	dijkstra();


	for(int i = 1; i <= n; i ++ )
	{
		int x;
		cin >> x;
		if(i != x && i != n) add(i, i + n, x);
		else add(i, i + n, INF);
	}
	cout << dinic() << '\n';
}

C++ 解法, 执行用时: 32ms, 内存消耗: 2972K, 提交时间: 2022-07-07 14:43:39

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=4e5+5,mod=1e9+7;
const ll inf=1e15;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int n,m,cnt=1,cnt1=1,h[N],h1[N],st,ed,dep[N],cur[N],vis[N];
ll d[N];
struct edge{
	int to,nt;ll w;
}e[M],e1[M];
void add(int u,int v,ll w){
	e[++cnt]={v,h[u],w},h[u]=cnt;
	e[++cnt]={u,h[v],w},h[v]=cnt;
}
void Add(int u,int v,ll w){
	e1[++cnt1]={v,h1[u],w},h1[u]=cnt1;
	e1[++cnt1]={u,h1[v],0},h1[v]=cnt1;
}
bool bfs(){
	queue<int>q;q.push(st),mst(dep,0),dep[st]=1;
	while(!q.empty()){
		int  u=q.front();q.pop();cur[u]=h1[u];
		for(int i=h1[u];i;i=e1[i].nt){
			int v=e1[i].to;
			ll w=e1[i].w;
			if(w&&!dep[v]) dep[v]=dep[u]+1,q.push(v);
		}
	}return dep[ed];
}
ll dfs(int u,ll c){
	if(u==ed) return c;ll res=c;
	for(int &i=cur[u];i;i=e1[i].nt){
		int v=e1[i].to;
		ll w=e1[i].w;
		if(w&&dep[v]==dep[u]+1){
			ll now=dfs(v,min(res,1LL*w));
			if(!now) dep[v]=1;
			else e1[i].w-=now,e1[i^1].w+=now,res-=now;
		}if(!res) return c;
	} return c-res;
}
void spfa(){
	queue<int>q;q.push(st),mst(d,0x3f),d[st]=0;mst(vis,0),vis[st]=1;
	while(!q.empty()){
		int u=q.front();q.pop(),vis[u]=0;
		for(int i=h[u];i;i=e[i].nt){
			ll w=e[i].w;int v=e[i].to;
			if(d[v]>d[u]+w){
				d[v]=d[u]+w;
				if(!vis[v]) q.push(v),vis[v]=1;
			}
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=h[i];j;j=e[j].nt){
			int v=e[j].to;
			if(d[v]==d[i]+e[j].w) Add(i+n,v,inf);
		}
}
int main(){
	scanf("%d%d",&n,&m);st=1,ed=n<<1;
	for(int i=1,u,v,w;i<=m;i++){
		scanf("%d%d%d",&u,&v,&w),add(u,v,w);
	}
	spfa();
	for(int i=1,x;i<=n;i++){
		scanf("%d",&x);
		Add(i,i+n,(i==1||i==n)?inf:x);
	}ll s=0;
	while(bfs()) 
	s+=dfs(st,inf);
	printf("%lld\n",s);
	return 0;
}

上一题