目录
Codeforces Round 927 (Div. 3) G. Moving Platforms:
原题链接:Problem - G - Codeforces
题目大意:
思路解析:
代码实现:
Codeforces Round 927 (Div. 3) G. Moving Platforms:
原题链接:Problem - G - Codeforces
题目大意:
给你n个城市,m条道路,组成一个无向图,给你一个模数h,每个城市有一个初始价值为si,并且每个城市在每秒会有一个变化值li,当 (si+ t * li) mod h == (sj + t * lj) mod h时通道才会打开,问从第一个城市到最后一个城市最少需要多少时间,如果无法到达输出-1.
思路解析:
给你n个城市,m条道路,组成一个无向图,问从第一个城市到最后一个城市最少需要多少时间这里很容易可以想到需要用到最短路,但是在跑最短路时我们怎么判断当前两个城市是否能够进行转移,或者转移需要等待多长时间,便成了主要难点。
代码实现:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
int T = input.nextInt();
for (int o = 0; o < T; o++) {
int n = input.nextInt();
int m = input.nextInt();
int H = input.nextInt();
Vector<Integer> g[] = new Vector[n];
for (int i = 0; i < n; i++) {
g[i] = new Vector<>();
}
PriorityQueue<Node> nodes = new PriorityQueue<Node>(new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
if (o1.time > o2.time) return 1;
else if (o1.time == o2.time) return o1.x - o2.x;
return -1;
}
});
int[] l = new int[n+1];
long[] s = new long[n+1];
for (int i = 0; i < n; i++) {
l[i] = input.nextInt();
}
for (int i = 0; i < n; i++) {
s[i] = input.nextInt();
}
for (int i = 0; i < m; i++) {
int x = input.nextInt() - 1;
int y = input.nextInt() - 1;
g[x].add(y);
g[y].add(x);
}
long[] dp = new long[n];
Arrays.fill(dp, (long) 1e18);
dp[0] = 0;
nodes.add(new Node(0, dp[0]));
while (!nodes.isEmpty()){
Node cur = nodes.poll();
int v = cur.x;
long t = dp[v];
if (t < cur.time) continue; // 因为他可能里面存放了多个 u,dp[u]的点,选择当时加入时dp[u]最小的那个进行遍历即可
for (Integer u : g[v]) {
long a = (l[v] + (t % H) * s[v]) - (l[u] + (t % H) * s[u]);
a %= H;
if (a < 0) a += H;
long b = s[u] - s[v];
b %= H;
if (b < 0) b += H;
// a - bx = yH
long[] arr = eucl(b, H);
long dd = arr[0];
long x = arr[1];
// xb + yH = dd
if (a % dd != 0) continue;
x *= a / dd;
x %= (H / dd);
if (x < 0) x += H / dd;
long dt = x;
if (dp[v] + dt + 1 < dp[u]){
dp[u] = dp[v] + dt + 1;
nodes.add(new Node(u, dp[u]));
}
}
}
if (dp[n - 1] == (long) 1e18) out.println(-1);
else out.println(dp[n - 1]);
}
out.flush();
out.close();
br.close();
}
public static long[] eucl(long a, long b) { // 扩展欧几里得
if (b == 0) {
return new long[]{a, 1, 0}; //
}
long k = a / b;
long[] arr = eucl(b, a - k * b);
return new long[]{arr[0], arr[2], arr[1] - k * arr[2]};
}
public static class Node{
int x;
long time;
public Node(int x, long time){
this.x = x;
this.time = time;
}
}
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static Input input = new Input(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static class Input {
public BufferedReader reader;
public StringTokenizer tokenizer;
public Input(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}
}