标签:desc math ems etc 需要 8 8 并且 using int
给出一个无向图,Bessie从1号仓库走到n号(每次花费B), Elsie从2号仓库走到n号(每次花费E),如果两个人走同一条路花费P,求总花费最小。
输入B,E,P,n,m和m条边的联通情况。
输出最少花费。
4 4 5 8 8
1 4
2 3
3 4
4 7
2 5
5 6
6 8
7 8
22
\(1\le n,m,b,e,p\le 4×10^4,n \ge 3\)
首先这道题明显是一个最短路,和在一起考虑有一点麻烦,所以我们分开考虑。
对于 Bessie 和 Elsie 来说,他们走到任意一个点的最短路是非常好算的。假设他们现在都走到了点 \(i\),并且想要一起走到终点,那么我们只需要求出从点 \(n\) 到点 \(i\) 的距离,最后对所有的值取最小值即可。
时间复杂度为 \(\mathcal{O(k\times n)}\) (SPFA 时间复杂度)
#include <bits/stdc++.h>
using namespace std;
const int N = 100007;
int dis[4][N],inq[4][N],head[N];
int m,n,u,v,b,e,p,cnt = 0,ans = 2147483647;
struct node {
int v,nxt;
node() {}
node(int _v,int _nxt) {
v = _v; nxt = _nxt;
}
}E[N];
template <class T> inline void read(T &x) {
x = 0;
int p = 1;
char ch = getchar();
while(ch < ‘0‘ || ch > ‘9‘) {
if(ch == ‘-‘) p = -1;
ch = getchar();
}
while(ch >= ‘0‘ && ch <= ‘9‘) {
x = x * 10 + ch - ‘0‘;
ch = getchar();
}
x = x * p;
}
void add_edge(int u,int v) {
E[++cnt] = node(v,head[u]);
head[u] = cnt;
}
void spfa(int id,int st) { //SPFA
int wi;
if(id == 1) wi = b;
if(id == 2) wi = e;
if(id == 3) wi = p;
queue <int> q;
memset(dis[id],0x3f,sizeof(dis[id]));
memset(inq[id],0,sizeof(inq[id]));
dis[id][st] = 0; inq[id][st] = 1;
q.push(st);
while(!q.empty()) {
int u = q.front(); q.pop();
inq[id][u] = 0;
for(int i = head[u];i != 0;i = E[i].nxt) {
int v = E[i].v;
if(dis[id][v] > dis[id][u] + wi) {
dis[id][v] = dis[id][u] + wi;
if(!inq[id][v]) {
inq[id][v] = 1;
q.push(v);
}
}
}
}
}
int main() {
read(b); read(e); read(p); read(n); read(m);
for(int i = 1;i <= m;i++) {
read(u); read(v);
add_edge(u,v);
add_edge(v,u);
}
spfa(1,1); spfa(2,2); spfa(3,n);
// 1表示Bessie,2表示Elsie,3表示他们一起走
for(int i = 1;i <= n;i++) {
ans = min(ans,dis[1][i] + dis[2][i] + dis[3][i]);//取最小值
}
printf("%d\n",ans);
return 0;
}
P3110 [USACO14DEC]Piggy Back S 题解
标签:desc math ems etc 需要 8 8 并且 using int
原文地址:https://www.cnblogs.com/trz-2007/p/13994956.html