(beginer) 最短路 UVA 11280 Flying to Fredericton

来源:互联网 发布:精华液推荐 知乎 编辑:程序博客网 时间:2024/06/09 15:06

Problem C

FLYING TO FREDERICTON

After being inspired by Salvador Dali's artwork, Brett decided he would like to travel to Fredericton, New Brunswick to visit the Beaverbrook Art Gallery.

Brett lives in Calgary, and would like to find the cheapest flight or flights that would take him to Fredericton. He knows that a direct flight from Calgary to Fredericton, if one exists, would be absurdly expensive, so he is willing to tolerate a certain number of stopovers. However, there are multiple airlines in Canada with so many different flights between different cities now, which makes it very difficult for Brett to find the least expensive way to Fredericton! Can you write a program to help Brett plan his route?

(beginer) 最短路 UVA 11280 Flying to Fredericton - 恶魔仁 - 恶魔仁

Map showing a sample of the flights that would take Brett to Fredericton.

You will be given a list of cities between and including Calgary and Fredericton. The cities will be given in order of "nearest" to "farthest". The first city will always be "Calgary" and the last "Fredericton".

You will also be given a list of flights between pairs of cities, and the associated cost for each flight, taxes included. There will never be a flight from a farther city to a nearer city - Brett has already discarded those flights, deeming them to be a waste of time and money. Bear in mind, however, that there may be more than one flight between any two cities, as Brett is considering flights from all airlines.

Finally, you are presented with a number of queries. Each query is a single integer indicating the maximum number of stopovers Brett will tolerate. For each query, your program must calculate the least total cost of flights that would take Brett from Calgary to Fredericton with no more than the requested number of stopovers.

Input

The first line of input contains a single number indicating the number of scenarios to process. A blank line precedes each scenario.

Each scenario begins with a number N (2 ≤ N ≤ 100), the number of cities, followed by N lines containing the names of the cities. A city name is a string of up to 20 uppercase and lowercase letters. Next is a number M (0 ≤ M ≤ 1000), the number of flights available, followed by M lines describing the flights. Each flight is described by its departure city, its destination city, and an integer representing its cost in dollars. The final line starts with Q (1 ≤ Q ≤ 10), the number of queries, followed by Q numbers indicating the maximum number of stopovers.

Output

For each scenario, your program should output the scenario number, followed by the least total cost of the flights for each query. Follow the format of the sample output. If no flights can satisfy a query, write "No satisfactory flights". Output a blank line between scenarios.

Sample Input

24CalgaryWinnipegOttawaFredericton6Calgary Winnipeg 125Calgary Ottawa 300Winnipeg Fredericton 325Winnipeg Ottawa 100Calgary Fredericton 875Ottawa Fredericton 1753 2 1 03CalgaryMontrealFredericton2Calgary Montreal 300Montreal Fredericton 3251 0

Output for the Sample Input

Scenario #1Total cost of flight(s) is $400Total cost of flight(s) is $450Total cost of flight(s) is $875Scenario #2No satisfactory flights

题意:起点是Cal...终点是Fre.... 规定中间停留的次数,问最少花费。。。模板题

思路:d[i][j]到达i,还有j次停留机会的最小花费。注意到达目的地就不算停留了s->u1->u2-t,这里面s是起点,t是终点的话只停留了2次。所以当stopover=0时,s->t 这种是合法的。其他就套模板就行了

代码:
#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<map>
#include<string>
#include<string.h>
using namespace std;
const int maxn = 110;
const int inf = 1e9;
int n , m , size , ptr , Q , d[maxn][maxn];
bool done[maxn][maxn];

map<string,int> cityno;

struct State
{
State(int uu,int dd,int ss) : u(uu) , dist(dd) , sp(ss) { }
int u;
int dist;
int sp;
};

inline bool operator < (const State & s1 , const State & s2)
{
return s1.dist > s2.dist;
}

struct Node 
{
int v;
Node *next;
int w;
}edge[2000+5] , *first[maxn];

void init()
{
memset(first,0,sizeof(first));
ptr = 0;
}

void add(int x,int y,int w)
{
edge[++ptr].v = y;
edge[ptr].w = w;
edge[ptr].next = first[x];
first[x] = &edge[ptr];
}

char buffer[30];
string s1;
void input()
{
cityno.clear();
for (int i = 1 ; i <= n ; ++i)
{
scanf("%s",buffer);
s1 = buffer;
cityno[s1] = i;
}
scanf("%d",&m);
size = n;
int u , v , w;
while (m--)
{
scanf("%s",buffer);  s1 = buffer;
if (cityno.count(s1)) u = cityno[s1];
else u = cityno[s1] = ++size;
scanf("%s%d",buffer,&w); s1 = buffer;
if (cityno.count(s1)) v = cityno[s1];
else v = cityno[s1] = ++size;
add(u,v,w);
}
}

void Dij(int sp)
{
int s = cityno["Calgary"];
int t = cityno["Fredericton"];
memset(done,0,sizeof(done));
sp = min(size,sp);
for (int i = 1 ; i <= size ; ++i) for (int j = 0 ; j <= sp ; ++j) 
d[i][j] = inf;
priority_queue<State> q;
q.push(State(s,0,sp));
d[s][sp] = 0;
int u , v , w , stop;
Node * p;
while (q.size())
{
State tmp = q.top(); q.pop();
u = tmp.u , stop = tmp.sp;
if (done[u][stop]) continue;
done[u][stop] = true;
if (u==t) { printf("Total cost of flight(s) is $%d\n",tmp.dist); return; }
for (p = first[u] ; p ; p = p->next) 
{
v = p->v;
w = p->w;
int to = stop-(v!=t);
if (d[v][to] > d[u][stop]+w)
{
d[v][to] = d[u][stop]+w;
q.push(State(v,d[v][to],to));
}
}
}
printf("No satisfactory flights\n");
}

void solve()
{
scanf("%d",&Q);
int sp;
while (Q--)
{
scanf("%d",&sp);
Dij(sp);
}
}

int main()
{
int T; cin>>T;
int k = 0;
while (T--)
{
scanf("%d",&n);
++k;
init();
input();
printf("Scenario #%d\n",k);
solve();
if (T) cout << endl;
}
}
0 0
原创粉丝点击