[USACO09DEC]牛收费路径Cow Toll Paths

题意

有一张无向无环连通图,点和边均有权值。一条路径的值等于路径上点的最大值加上边之和。

多次询问,两点之间路径最小值。


思路

每个点跑一遍dijkstra,判断是否取点加入点值。

代码

#include <bits/stdc++.h>

using namespace std;

namespace StandardIO {

	template<typename T> inline void read (T &x) {
		x=0;T f=1;char c=getchar();
		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
		x*=f;
	}
	template<typename T> inline void write (T x) {
		if (x<0) putchar('-'),x=-x;
		if (x>=10) write(x/10);
		putchar(x%10+'0');
	}

}

using namespace StandardIO;

namespace Solve {
	#define int long long
	
	const int N=300;
	const int INF=0x3f3f3f3f3f3f3f3f;
	
	int n,m,k;
	int G[N][N];
	struct node {
		int to,val;
		node () {to=val=0;}
		node (int x,int v) : to(x),val(v) {}
		friend bool operator < (node a,node b) {
			if (a.val!=b.val) return a.val>b.val;
			return a.to>b.to;
		}
	};
	int c[N];
	int dis[N][N];

	inline void dijkstra (int a) {
		priority_queue<node> Q;
		Q.push(node(a,0));
		while (!Q.empty()) {
			node now=Q.top();Q.pop();
			if (dis[a][now.to]!=INF) continue;
			dis[a][now.to]=now.val;
			for (register int i=1; i<=n; ++i) {
				if (c[i]>c[a]||G[now.to][i]==INF) continue;
				Q.push(node(i,G[now.to][i]+dis[a][now.to]));
			}
		}
	}
	
	inline void MAIN () {
		memset(G,0x3f,sizeof(G));
		memset(dis,0x3f,sizeof(dis));
		read(n),read(m),read(k);
		for (register int i=1; i<=n; ++i) {
			read(c[i]),G[i][i]=0;
		}
		for (register int i=1; i<=m; ++i) {
			int x,y,z;
			read(x),read(y),read(z);
			G[x][y]=G[y][x]=min(G[x][y],z);
		}
		for (register int i=1; i<=n; ++i) dijkstra(i);
		while (k--) {
			int s,t,ans=INF;
			read(s),read(t);
			for (register int i=1; i<=n; ++i) {
				if (c[i]>=c[s]&&c[i]>=c[t]) {
					ans=min(ans,dis[i][s]+dis[i][t]+c[i]);
				}
			}
			write(ans),putchar('
');
		}
	}
	
	#undef int
}

int main () {
	Solve::MAIN();
}
原文地址:https://www.cnblogs.com/ilverene/p/11368727.html