您的位置:首页 > 产品设计 > UI/UE

CF 一个不知道题号的题。。 B. ShortestPath Query

2015-09-21 22:16 375 查看
B. ShortestPath Query

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

De Prezer loves troyic paths.Consider we have a graph with n vertices
and m edges.Edges are directed in one way.And there is at most one edge from any vertex to any other vertex.If there is an edge from v to u,
then c(v, u) is its color and w(v, u) is
its length.Otherwise,c(v, u) = w(v, u) =  - 1.

A sequence p1, p2, ..., pk is
a troyic path is and only if for each 1 ≤ i ≤ k, 1 ≤ pi ≤ n and
if i < k, then c(pi, pi + 1) >  - 1 and
if i + 1 < k, then c(pi, pi + 1) ≠ c(pi + 1, pi + 2) .

The length of such troyic path is

and
it's called a p1 - pk path.

In such graph, length of the shortest path from vertex v to u is
the minimum length of all v - u paths.(The length of the shortest path from any vertex to itself equals 0)

De Prezer gives you a graph like above and a vertex s.

De Prezer also loves query. So he gives you q queries and in each query, gives you number t and
you should print the length of the shortest path from s to t (or  - 1 if
there is no troyic path from s to t)

Input

The first line of input contains three integers n and m and C,
the number of vertices, the numbers of edges and the number of valid colors.

The next m lines, each line contains 4 integers v, u, w(v, u), c(v, u) (1 ≤ v, u ≤ n and v ≠ u and 1 ≤ w(v, u) ≤ 109 and1 ≤ c(v, u) ≤ C).

The line after that contains integer s and q.

The next q lines, each line contains information of one query, number t.

1 ≤ n, m, C, q ≤ 105

m ≤ n(n - 1)

1 ≤ s, t ≤ n

Output

For each query, print the answer.

Sample test(s)

input
5 4 1000
1 2 10 1
2 3 10 2
3 4 10 2
4 5 10 1
1 5
1
2
3
4
5


output
0
10
20
-1
-1


input
5 5 2
1 2 10 1
2 3 10 2
3 4 10 1
4 5 10 2
1 5 39 1
1 5
1
2
3
4
5


output
0
10
20
30
39


题目就是求路径中任意两条边颜色不同的最短路径。然后思路就是记录最短路和与最短路颜色不同的最短路,其实就是最短路和次短路(不同颜色),然后dijkstra算法优先队列搞一下就好了。

#pragma warning(disable:4996)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
typedef long long LL;
const LL inf = 10000000000000000LL;
const int N = 100005;

struct node {
LL len;
int pos, col;
node(){}
node(int pos, LL len, int col) :pos(pos), len(len), col(col) {}
bool operator<(const node &op)const {
return len > op.len;
}
};

int fst
, nxt
, to
, c
, w
, e;
int n, m, C;
LL dis
[2];//0->最小,1->跟最小颜色不同的次小
int color
[2];//相应颜色

void add(int u, int v, int len, int col) {
to[e] = v;
w[e] = len;
c[e] = col;
nxt[e] = fst[u];
fst[u] = e++;
}

void dijkstra(int s) {
priority_queue<node>q;
for (int i = 1; i <= n; i++) {
dis[i][0] = dis[i][1] = inf;
}
memset(color, 0, sizeof color);
dis[s][0] = dis[s][1] = 0;
q.push(node(s, 0, 0));
while (!q.empty()) {
node now = q.top(); q.pop();
int u = now.pos;
for (int i = fst[u]; ~i; i = nxt[i]) {
int v = to[i], col = c[i], len = w[i];
if (col == now.col)continue;
if (dis[v][0] > now.len + len) {
dis[v][0] = now.len + len;
color[v][0] = col;
q.push(node(v, dis[v][0], color[v][0]));
}
//注意这里判断一下颜色不能跟最短路的一样!!!
else if (color[v][0] != col&&dis[v][1] > now.len + len) {
dis[v][1] = now.len + len;
color[v][1] = col;
q.push(node(v, dis[v][1], color[v][1]));
}
}
}

}

int main() {
e = 0;
memset(fst, -1, sizeof fst);
scanf("%d%d%d", &n, &m, &C);
for (int i = 1; i <= m; i++) {
int u, v, len, col;
scanf("%d%d%d%d", &u, &v, &len, &col);
add(u, v, len, col);
}

int q, s;
scanf("%d%d", &s, &q);
dijkstra(s);
while (q--) {
int t; scanf("%d", &t);
if (dis[t][0] == inf)dis[t][0] = -1;
printf("%I64d\n", dis[t][0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: