洛谷 P2984 [USACO10FEB]给巧克力Chocolate Giving
Description
- Farmer
John有B头奶牛(1<=B<=25000),有N(2*B<=N<=50000)个农场,编号1-N,有M(N-1<=M<=100000)条双向边,第i条边连接农场R_i和S_i(1<=R_i<=N;1<=S_i<=N),该边的长度是L_i(1<=L_i<=2000)。居住在农场P_i的奶牛A(1<=P_i<=N),它想送一份新年礼物给居住在农场Q_i(1<=Q_i<=N)的奶牛B,但是奶牛A必须先到FJ(居住在编号1的农场)那里取礼物,然后再送给奶牛B。你的任务是:奶牛A至少需要走多远的路程?
Input
-
* Line 1: Three space separated integers: N, M, and B
* Lines 2..M+1: Line i+1 describes cowpath i with three
space-separated integers: R_i, S_i, and L_i
* Lines M+2..M+B+1: Line M+i+1 contains two space separated integers: P_i and Q_i
Output
- Lines 1..B: Line i should contain a single integer, the smallest
distance that the bull in pasture P_i must travel to get chocolates from
the barn and then award them to the cow of his dreams in pasture Q_i
Sample Input
6 7 3 1 2 3 5 4 3 3 1 1 6 1 9 3 4 2 1 4 4 3 2 2 2 4 5 1 3 6
Sample Output
6 6 10
题解:
- 挺水的一道图论。
- 反向跑最短路即可,这是一个技巧,像我们这种
萌新需要熟练掌握
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define N 50005
#define M 200005
using namespace std;
struct Node
{
int val, pos;
friend bool operator < (Node x, Node y) {
return x.val > y.val;
}
};
struct E {int next, to, dis;} e[M];
int n, m, q, num;
int h[N], dis[N];
bool vis[N];
int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x;
}
void add(int u, int v, int w)
{
e[++num].next = h[u];
e[num].to = v;
e[num].dis = w;
h[u] = num;
}
void dijkstra()
{
priority_queue<Node> que;
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0, que.push((Node){0, 1});
while(que.size())
{
int now = que.top().pos;
que.pop();
if(vis[now]) continue;
vis[now] = 1;
for(int i = h[now]; i != 0; i = e[i].next)
if(dis[now] + e[i].dis < dis[e[i].to])
{
dis[e[i].to] = dis[now] + e[i].dis;
if(!vis[e[i].to]) que.push((Node){dis[e[i].to], e[i].to});
}
}
}
int main()
{
cin >> n >> m >> q;
for(int i = 1; i <= m; i++)
{
int u = read(), v = read(), w = read();
add(u, v, w), add(v, u, w);
}
dijkstra();
for(int i = 1; i <= q; i++)
{
int u = read(), v = read();
printf("%d\n", dis[u] + dis[v]);
}
return 0;
}