UVa 10246 Asterix and Obelix(变形的最短路径)

10246 - Asterix and Obelix

Time limit: 3.000 seconds

Problem A

Asterix and Obelix

Input: standard input

Output: standard output

Time Limit: 5 seconds

Memory Limit: 32 MB

After winning a gruesome battle against the Romans in a far-away land, Asterix and his dearest friend Obelix are now returning home. However Obelix is not with Asterix now. He has left Asterix in order to deliver menhir to one of his
international buyers (as you probably 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 to host a feast for Obelix (you know how fat he is!) in the city they meet.
Obelix may meet Asterix in any city on his way home including the starting and the destination city.

Now Asterix is sitting with a map and trying to figure out the cheapest route home. The map shows the cities and the cost (in sestertii) of going from one city to another if there is a road connecting them directly. For each city in
the map Asterix has also calculated the cost (in sestertii) of hosting a feast for Obelix in that city. There will be only one feast and for safety Asterix has decided to set aside enough sestertii to host a feast in the costliest city on the route.

Since Asterix does not have a computer, he seeks your help to find out the cheapest route home.

Input

The input may contain multiple test cases.

The first line of each test case contains three integers C (£ 80)R (£ 1000) and Q (£ 6320) where C indicates the number of cities (cities are numbered using distinct
integers ranging from 1 to C), R represents the number of roads and Q is the number of queries.

The next line contains C integers where the i-th integer fi is the cost (in sestertii) of hosting a feast in city i.

Each of the next R lines contains three integers: c1, c2 (1 c1) and d indicating that the cost of going from city cto c2 (or
from cto c1) is d sestertii.

Each of the next Q lines contains two integers c1 and c2 (c1 c2) asking for the cost (in sestertii) of the cheapest route from city cto
city c2.

The input will terminate with three zeros form CS and Q.

Output

For each test case in the input first output the test case number (starting from 1) as shown in the sample output. 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. If there exists no path between them just print “–1”.

Print a blank line between two consecutive test cases.

 

Sample Input

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

 

Sample Output

Case #1

45

-1

45

35

16

Case #2

18

20

思路:spfa求出每个点到其余顶点的最短路(最短路上的每个点的val都小于等于

起点的val),然后又二维数组dis来保存,最后询问的时候就是枚举中间点i了.

ans = min{dis[i][u]+dis[i][v]+cost[i]};

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;
const int inf=999999999;
const int maxn=110;

struct node
{
    int v,t;
    node(){}
    node(int _v,int _t):v(_v),t(_t){}
};
vector <node> G[maxn];
int C,R,Q,cnt,dis[maxn][maxn],W[maxn];
bool visited[maxn];

void spfa(int x)
{
    memset(visited,0,sizeof(visited));
    queue <int> q;
    q.push(x);
    dis[x][x]=0;
    visited[x]=1;
    while(!q.empty())
    {
        int c=q.front();
        q.pop();
        visited[c]=0;
        for(int i=0; i<G[c].size(); i++)
        {
            int v=G[c][i].v;
            if(dis[x][v]>dis[x][c]+G[c][i].t && W[x]>=W[v])
            {
                dis[x][v]=dis[x][c]+G[c][i].t;
                if(!visited[v])
                {
                    q.push(v);
                    visited[v]=1;
                }
            }
        }
    }
}

void initial()
{
    for(int i=0;i<maxn;i++)  G[i].clear();
    for(int i=0;i<maxn;i++)
        for(int j=0;j<maxn;j++)
            dis[i][j]=inf;
}

void input()
{
    int x,y,z;
    for(int i=1;i<=C;i++)  scanf("%d",&W[i]);
    for(int i=0;i<R;i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        G[x].push_back(node(y,z));
        G[y].push_back(node(x,z));
    }
}

void solve()
{
     int x,y;
     for(int i=1;i<=C;i++)  spfa(i);
     printf("Case #%d\n",++cnt);

     for(int co=0;co<Q;co++)
     {
         scanf("%d %d",&x,&y);
         int ans=inf;
         for(int i=1;i<=C;i++)   ans=min(ans,dis[i][x]+dis[i][y]+W[i]);
         if(ans<inf)  printf("%d\n",ans);
         else  printf("-1\n");
     }
}

int main()
{
     while(scanf("%d %d %d",&C,&R,&Q)!=EOF)
     {
         if(C==0 && R==0 && Q==0) break;
         if(cnt)  printf("\n");
         initial();
         input();
         solve();
     }
     return 0;
}

时间: 2024-11-05 04:07:12

UVa 10246 Asterix and Obelix(变形的最短路径)的相关文章

UVA 10246 - Asterix and Obelix(最短路)

UVA 10246 - Asterix and Obelix 题目链接 题意:给定一个图,每个点有一个代价,边有一个代价,现在有q次询问,每次询问从u到v的最小花费,花费的计算方式为,路径代价加上路径上最大代价结点的代价 思路:枚举最大代价结点,然后做dijkstra,做的过程中忽略掉比枚举点更大代价的点,然后更新所有的答案,预处理完成后每次询问就可以在O(1)时间内完成了 代码: #include <cstdio> #include <cstring> #include <

Don&#39;t Get Rooked UVA 639(八皇后问题变形)

说说: 这道题目类似于八皇后问题.有n*n的正方形棋盘,且n<=4.例如在n=4时,有下图所示的棋盘,其中每两个棋子不能放在同一行或者同一列,除非有围墙(黑色的格子)将它们隔开.求给定的棋盘,能放下的最多的棋子数目. 分析: 在八皇后问题中,我们对整个棋盘分成八行考虑的,每行插入一个棋子.所以对于这道题目解决方案也类似,同样是一行一行插入.但是与八皇后问题不同的是,本题中棋盘一行可能插入多个棋子,也可能没有棋子.所以在递归函数中,不仅要给出所要处理的行的信息,也要给出所要处理的列的信息,其实就是

UVa 1394 约瑟夫问题的变形

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4140 本来是要昨天来写这学习代码的,然后昨晚寝室又断电了,忍不住在这里吐槽一下,嗯,寝室天天断电. 题意就是输入n,k,m三个数,n个数排成一个圈,第一次删除m,以后每数k个数删除一次,求最后一个被删除的数. 言归正传,以前写过一个链表的约瑟夫问题,但是在这里肯定是会超时的.后来看了些参考

uva 10246

题意:图中有C个点,R条边,每个点有个权值,每条边也有距离值,求A到B点的最短距离+经过的点的最大值的和最小 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cstdlib> #include<string> #include<queue> #include<

uva_10246_Asterix and Obelix(最短路)

10246 Asterix and Obelix After winning a gruesome battle against the Romans in a faraway land, Asterix and his dearest friend Obelix are now returning home. However Obelix is not with Asterix now. He has left Asterix in order to delivermenhir to one

UVA 10256 The Great Divide(凸包划分)

The Great Divide Input: standard input Output: standard output Time Limit: 8 seconds Memory Limit: 32 MB Somewhere in Gaul, there is a little village very like the village where Asterix and Obelix live. Not very long ago they had only one chief Altru

uva 10537 Toll! Revisited(优先队列优化dijstra及变形)

Toll! Revisited 大致题意:有两种节点,一种是大写字母,一种是小写字母.首先输入m条边,当经过小写字母时需要付一单位的过路费,当经过大写字母时,要付当前财务的1/20做过路费.问在起点最少需要带多少物品使到达终点时还有k个物品.当有多条符合条件的路径时输出字典序最小的一个. 思路:已知终点的权值,那么可以从终点向前推.求终点到起点的最短路径,然后按字典序打印路径. 比较难处理的是:向前推时前驱节点的权值计算.列个方程算算就可以了,主要时不能整除的情况. 计算前驱结点dis值的时候,

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 658 It&#39;s not a Bug, it&#39;s a Feature! (单源最短路,dijkstra+优先队列,变形,经典)

题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了:要打多久才能无bug?(同1补丁可重复打) 分析: n<=20,那么用位来表示bug的话有220=100万多一点.不用建图了,图实在太大了,用位图又不好玩.那么直接用隐式图搜索(在任意点,只要满足转移条件,任何状态都能转). 但是有没有可能每个状态都要搜1次啊?那可能是100万*100万啊,这样出题