【codeforce Gym 100570B】【最短路SPFA】 ShortestPath Query 【询问单源最短路径,每条边有一个颜色,要求路径上相邻边的颜色不能相同】
2016-10-14 15:37
591 查看
传送门:gym 100570B
描述:
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
![](http://codeforces.com/predownloaded/7b/e5/7be5a8e28fcbc13e2ab916d86bbdedd084e2b7d2.png)
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 and 1 ≤ 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.
Examples
input
output
input
output
题意:
询问单源最短路径,每条边有一个颜色,要求路径上相邻边的颜色不能相同,无重边且边权为正。
思路:
因为路径的合法性和边的颜色有关,
所以在做spfa的时候,把边丢到队列中去,松弛的时候注意判断一下颜色,d数组表示到这条边的出点v的距离。
期望复杂度是O(km),k是边入队次数,m是边数。最后根据边来松弛顶点,O(m),总复杂度是O(km+m)。
一开始想的Dijkstra(看到边权为正。。),存点和之前边的颜色每次更新的时候判断来的那个点的颜色和当前边的颜色是否一样,WA了,很快我就意识到,入点不能只保存最短路径的颜色c1,如果边的颜色和c1一样,那么会判成路径不合法,但是实际上可能还存在一条次短路径且颜色和c1不等,所以不能只存点的颜色,应该按照题意用spfa去跑并且满足相邻边的颜色不同。
代码:
描述:
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
![](http://codeforces.com/predownloaded/7b/e5/7be5a8e28fcbc13e2ab916d86bbdedd084e2b7d2.png)
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 and 1 ≤ 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.
Examples
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
题意:
询问单源最短路径,每条边有一个颜色,要求路径上相邻边的颜色不能相同,无重边且边权为正。
思路:
因为路径的合法性和边的颜色有关,
所以在做spfa的时候,把边丢到队列中去,松弛的时候注意判断一下颜色,d数组表示到这条边的出点v的距离。
期望复杂度是O(km),k是边入队次数,m是边数。最后根据边来松弛顶点,O(m),总复杂度是O(km+m)。
一开始想的Dijkstra(看到边权为正。。),存点和之前边的颜色每次更新的时候判断来的那个点的颜色和当前边的颜色是否一样,WA了,很快我就意识到,入点不能只保存最短路径的颜色c1,如果边的颜色和c1一样,那么会判成路径不合法,但是实际上可能还存在一条次短路径且颜色和c1不等,所以不能只存点的颜色,应该按照题意用spfa去跑并且满足相邻边的颜色不同。
代码:
#include <bits/stdc++.h> using namespace std; #define ll __int64 #define rep(i,k,n) for(int i=k;i<=n;i++) template<class T> T sqr(T x){ return x * x; } template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; } template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } const ll inf = 0x3f3f3f3f3f3f3f3fLL; const int N=1e5+10; int head , to , nxt , col , wei , vis , etol; ll d ;//edge ll dd ;//vertex int n, m, s, t, C, q; void spfa(){ memset(d, 0x3f, sizeof(ll) * m); memset(vis, 0, sizeof(vis)); queue<int>q; for(int i = head[s]; ~i; i = nxt[i]){//把s作为入点的边先加入队列 q.push(i); vis[i] = 1; d[i] = wei[i]; } while(!q.empty()){ int e = q.front(); q.pop(); vis[e] = 0; for(int i = head[to[e]]; ~i; i = nxt[i]){ if(col[i] != col[e] && wei[i] + d[e] < d[i]){ d[i] = wei[i] + d[e]; if(!vis[i]){ q.push(i); vis[i] = 1;} } } } memset(dd+1, 0x3f, sizeof(ll) * n); dd[s]=0; rep(i, 0, m-1){ dd[to[i]] = min(dd[to[i]], d[i]); } } inline void addedge(int u, int v, int w, int c){ to[etol] = v; wei[etol] = w; col[etol] = c; nxt[etol] = head[u]; head[u] = etol++; } int main(){ read(n),read(m),read(C); memset(head+1, -1, sizeof(int) * n); rep(i, 1, m){ int u, v, w, c; read(u),read(v),read(w),read(c); addedge(u, v, w, c); } read(s),read(q); spfa(); rep(i, 1, q){ read(t); printf("%I64d\n", dd[t] == inf ? -1: dd[t]); } return 0; }
相关文章推荐
- Gym - 100570B :ShortestPath Query(SPFA及其优化)
- AOJ GRL_1_B: Shortest Path - Single Source Shortest Path (Negative Edges) (Bellman-Frod算法求负圈和单源最短路径)
- ZOJ 2760--How Many Shortest Path【dinic最大流 && 最短路构图 && 求最短路径的条数】
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现(C/C++)
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现(C/C++)
- codeforce Gym 100570B ShortestPath Query (最短路SPFA)
- zoj 2760 How Many Shortest Path 【最短路 + 最大流】 【求边不重复最短路径条数】
- 第十三章 ALDS1_12_B:Single Source Shortest Path I 单源最短路径
- hdoj 1535 Invitation Cards 【最短路径SPFA】【正反向建边求单源最短路之和】
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现
- ZOJ 2760 How Many Shortest Path (不相交的最短路径个数)
- RIP和OSPF(Open Shortest Path First开放式最短路径优先) 区别
- HDU 1535 Invitation Cards(有向图单源最短路径+SPFA)
- 用java编写的一个迪杰斯特拉算法(单源最短路径算法,Dijkstra算法)。
- hdu 2544 最短路(最短路径)(flody、dij、dij+priority queue、bellman、spfa)
- Algorithms Part 1-Question 5- Dijkstra's shortest-path-最短路径算法
- 字符串匹配之通配符问题------一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。
- Codeforce 295B Greg and Graph 活用Floyd 任意两点的最短路径
- 字符串匹配之通配符问题------一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。
- 最短路 dijkstra 权值非负的单源最短路径