UVa10246 - Asterix and Obelix(最短路径变形)
来源:互联网 发布:什么是网络喷子 编辑:程序博客网 时间:2024/06/05 01:56
After winning a gruesome battleagainst the Romans in a far-away land, Asterix and his dearest friend Obelixare now returning home. However Obelix is not with Asterix now. He has leftAsterix in order to deliver menhir to one of his international buyers (as youprobably know, recently he has extended his trade to international markets).But he has promised to join Asterix on his way home and Asterix has promised tohost a feast for Obelix (you know how fat he is!) in the city they meet. Obelixmay meet Asterix in any city on his way home including the starting and thedestination city.
Now Asterix is sitting with a mapand trying to figure out the cheapest route home. The map shows the cities andthe cost (in sestertii) of going from one city to another if there is a roadconnecting them directly. For each city in the map Asterix has also calculatedthe cost (in sestertii) of hosting a feast for Obelix in that city. There willbe only one feast and for safety Asterix has decided to set aside enoughsestertii to host a feast in the costliest city on the route.
Since Asterix does not have acomputer, he seeks your help to find out the cheapest route home.
Input
The input may contain multipletest cases.
The first line of each test casecontains three integers C (£ 80),R (£1000) and Q (£ 6320) where C indicates thenumber of cities (cities are numbered using distinct integers ranging from 1 toC),Rrepresents the number of roads andQ is the number of queries.
The next line contains Cintegers where the i-th integerfi isthe cost (in sestertii) of hosting a feast in cityi.
Each of the next Rlines contains three integers: c1, c2 (¹ c1) anddindicating that the cost of going from city c1 to c2 (orfrom c2 toc1)isd sestertii.
Each of the next Qlines contains two integers c1 andc2(c1 ¹ c2)asking for the cost (in sestertii) of the cheapest route from cityc1 to city c2.
The input will terminate withthree zeros form C, S andQ.
Output
For each test case in the inputfirst output the test case number (starting from 1) as shown in the sampleoutput. Then for each query in the input print a line giving the minimum cost(in sestertii) of going from the first to the second city in the query. Ifthere exists no path between them just print “–1”.
Print a blank line between twoconsecutive test cases.
SampleInput
7 8 5
2 3 5 15 4 4 6
1 2 20
1 4 20
1 5 50
2 3 10
3 4 10
3 5 10
4 5 15
6 7 10
1 5
1 6
5 1
3 1
6 7
4 4 2
2 1 8 3
1 2 7
1 3 5
2 4 8
3 4 6
1 4
2 3
0 0 0
SampleOutput
Case#1
45
-1
45
35
16
Case#2
18
20
题意:在从s到t的路径中选取一点u,使得u点的权值最大,其它的点的权值小于u点的权值, 并且从s到t的路径最短思路:找到从u到s和从u到t的最短路径,使得路径上点的权值小于等于u点的权值,用Dijkstra或者SPFA找到从s点到其它点的最短路径(路径上的点的权值都小于等于s点的权值),然后查找min{f[s][u] + f[u][t] + cost[u]}的最小值即可
Dijkstra法代码如下,用的时间为0.046s
#include <cstdio>#include <vector>#include <queue>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 90;const int INF = 0x3f3f3f3f;struct Edge{ int from, to, w;};struct Node{ int u, d; bool operator < (const Node &other) const { return d > other.d; }};vector<int> adjList[MAXN];vector<Edge> edges;int cost[MAXN];int f[MAXN][MAXN];int c, r, q;int d[MAXN];bool vis[MAXN];int cas = 1;void addEdge(int u, int v, int w){ edges.push_back((Edge){u, v, w}); edges.push_back((Edge){v, u, w}); int size = edges.size(); adjList[u].push_back(size - 2); adjList[v].push_back(size - 1);}bool input(){ scanf("%d%d%d", &c, &r, &q); if (c + r + q == 0) return false; for (int i = 1; i <= c; i++) adjList[i].clear(); edges.clear(); for (int i = 1; i <= c; i++) { scanf("%d", &cost[i]); } for (int i = 0; i < r; i++) { int c1, c2, w; scanf("%d%d%d", &c1, &c2, &w); addEdge(c1, c2, w); } return true;}void dijkstra(int s){ priority_queue<Node> q; for (int i = 1; i <= c; i++) { d[i] = INF; } memset(vis, false, sizeof(vis)); d[s] = 0; q.push((Node){s, d[s]}); while (!q.empty()) { Node node = q.top(); q.pop(); int u = node.u; if (vis[u]) continue; vis[u] = true; for (int i = 0, size = adjList[u].size(); i < size; i++) { Edge& e = edges[adjList[u][i]]; if (cost[e.to] <= cost[s] && d[u] + e.w < d[e.to]) { d[e.to] = d[u] + e.w; q.push((Node){e.to, d[e.to]}); } } } for (int i = 1; i <= c; i++) { f[s][i] = d[i]; }}void solve(){ if (cas != 1) printf("\n"); printf("Case #%d\n", cas++); for (int i = 1; i <= c; i++) { dijkstra(i); } for (int i = 0; i < q; i++) { int c1, c2; scanf("%d%d", &c1, &c2); int ans = INF; for (int j = 1; j <= c; j++) { if (f[j][c1] == INF || f[j][c2] == INF) continue; ans = min(ans, f[j][c1] + f[j][c2] + cost[j]); } if (ans == INF) printf("-1\n"); else printf("%d\n", ans); }}int main() {#ifndef ONLINE_JUDGE freopen("d:\\OJ\\uva_in.txt", "r", stdin);#endif while (input()) { solve(); } return 0;}
SPFA法代码如下,用的时间为0.042s
#include <cstdio>#include <vector>#include <queue>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 90;const int INF = 0x3f3f3f3f;struct Edge{ int from, to, w;};vector<int> adjList[MAXN];vector<Edge> edges;int cost[MAXN];int f[MAXN][MAXN];int c, r, q;int d[MAXN];bool inq[MAXN];int cas = 1;void addEdge(int u, int v, int w){ edges.push_back((Edge){u, v, w}); edges.push_back((Edge){v, u, w}); int size = edges.size(); adjList[u].push_back(size - 2); adjList[v].push_back(size - 1);}bool input(){ scanf("%d%d%d", &c, &r, &q); if (c + r + q == 0) return false; for (int i = 1; i <= c; i++) adjList[i].clear(); edges.clear(); for (int i = 1; i <= c; i++) { scanf("%d", &cost[i]); } for (int i = 0; i < r; i++) { int c1, c2, w; scanf("%d%d%d", &c1, &c2, &w); addEdge(c1, c2, w); } return true;}void spfa(int s){ queue<int> q; for (int i = 1; i <= c; i++) { d[i] = INF; } memset(inq, false, sizeof(inq));d[s] = 0;inq[s] = true;q.push(s); while (!q.empty()) { int u = q.front(); q.pop();inq[u] = false; for (int i = 0, size = adjList[u].size(); i < size; i++) { Edge& e = edges[adjList[u][i]]; if (cost[e.to] <= cost[s] && d[u] + e.w < d[e.to]) { d[e.to] = d[u] + e.w; if (!inq[e.to]) {inq[e.to] = true;q.push(e.to);} } } } for (int i = 1; i <= c; i++) { f[s][i] = d[i]; }}void solve(){ if (cas != 1) printf("\n"); printf("Case #%d\n", cas++); for (int i = 1; i <= c; i++) { spfa(i); } for (int i = 0; i < q; i++) { int c1, c2; scanf("%d%d", &c1, &c2); int ans = INF; for (int j = 1; j <= c; j++) { if (f[j][c1] == INF || f[j][c2] == INF) continue; ans = min(ans, f[j][c1] + f[j][c2] + cost[j]); } if (ans == INF) printf("-1\n"); else printf("%d\n", ans); }}int main() {#ifndef ONLINE_JUDGE freopen("d:\\OJ\\uva_in.txt", "r", stdin);#endif while (input()) { solve(); } return 0;}
- UVa10246 - Asterix and Obelix(最短路径变形)
- uva10246- Asterix and Obelix
- UVa 10246 Asterix and Obelix(变形的最短路径)
- 10246 - Asterix and Obelix
- (beginer) 最短路 UVA 10246 Asterix and Obelix
- UVA 10246 - Asterix and Obelix(最短路)
- uva 10246 - Asterix and Obelix(最短路)
- uva 10246 Asterix and Obelix(最短路问题拓展 dijkstra)
- POJ2253 最短路径变形
- 变形的最短路径 POJ 3621
- POJ 2253 最短路径变形
- poj 1860 最短路径变形
- Arbitrage 最短路径的变形 flord
- uva_10246_Asterix and Obelix(最短路)
- 最短路径(4)--poj3268(dijkstra单源最短路径变形)
- 变形最短路径,最安全节点求解
- 最短路径(9)--poj1062(最短路简单变形)
- HDU 3790 最短路径问题 (最短路变形
- HTML学习笔记(1)-基础
- Github学习资料
- Dijkstra最短路径算法
- Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php
- 【MongoDB】windows平台搭建Mongo数据库复制集(类似集群)(一)
- UVa10246 - Asterix and Obelix(最短路径变形)
- Atitit.软件GUI按钮与仪表盘(01)--报警系统--
- linux LD_LIBRARY_PATH环境变量
- 南邮离散数学实验-利用真值表输出主析取范式主合取范式
- hdoj 1267 下沙的沙子有几粒? 【DP】
- 滚轮滚动 Webkit IE Moz的兼容
- 跟我一起学写jQuery插件开发方法(附完整实例及下载)
- Fragments for background processing
- java基础