UVA - 11280 Flying to Fredericton(二维SPFA)

来源:互联网 发布:数据库访问接口 xml 编辑:程序博客网 时间:2024/06/09 20:49


Link:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25133



Description

Download as PDF

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?

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

Brett Shikaze
Calgary Collegiate Programming Contest 2006


题意:给出n个城市和m条航线,每条航线连接两个城市,一个是航线的出发城市,一个是航线的抵达城市,并且有相应的花费。给出起点和目的地城市,然后有Q个询问,每个询问给出在起点和目的地城市路线中间最大可经过的城市数目,问在中间经过的城市数要小于等于最大可经过的城市数目的条件下,从指定的该起点城市到目的地城市的花费最少是多少。如果在该条件限制下不能抵达目的地,输出“No satisfactory flights”。


解题思路:要用二维来表示状态。一维表示到达某个城市的最短路径(也就是题目中的花费),第二维表示到达某个城市时中间经过的城市数目。同时该题输入数据比较麻烦,要用一些技巧对输入的数据进行处理,还要注意查询时输入数据可能不是合法的,这个也是一大坑点,要对数据判断后处理。剩下的就是裸的SPFA了。


AC code:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<map>#include<cmath>#define LL long long#define MAXN 1000010using namespace std;const int INF=0x3f3f3f3f;int n,m,tot;int head[MAXN];struct state{//用结构体来表示当前的状态:当前到达的城市编号为city,经过停留的城市数为stop int city;int stop;};struct node{int from;int to;int w;int next;}edge[MAXN];int dis[111][111];bool inq[111][111];int cnt[111][111];void init(){memset(head,-1,sizeof(head));tot=0;}void add(int from,int to,int w){edge[tot].from=from;edge[tot].to=to;edge[tot].w=w;edge[tot].next=head[from];head[from]=tot++;}bool spfa(int start,int ed){deque<state>q;memset(dis,INF,sizeof(dis));memset(inq,false,sizeof(inq));memset(cnt,0,sizeof(cnt));state st;st.city=start;st.stop=0;dis[st.city][st.stop]=0;q.push_back(st);inq[st.city][st.stop]=true;cnt[st.city][st.stop]++;while(!q.empty()){state now=q.front();q.pop_front();inq[now.city][now.stop]=false;if(cnt[now.city][now.stop]>n){continue;}if(cnt[now.city][now.stop]==n){dis[now.city][now.stop]=INF;}for(int i=head[now.city];i!=-1;i=edge[i].next){state nex;nex.city=edge[i].to;nex.stop=now.stop+1;if(dis[nex.city][nex.stop]>dis[now.city][now.stop]+edge[i].w){dis[nex.city][nex.stop]=dis[now.city][now.stop]+edge[i].w;if(!inq[nex.city][nex.stop]){state front=q.front();if(!q.empty()&&dis[nex.city][nex.stop]<dis[front.city][front.stop]){q.push_front(nex);}else{q.push_back(nex);}}}}}return true;}int main(){//freopen("D:\in.txt","r",stdin);int T,cas,i,j,u,v,w,Q,s,ans;scanf("%d",&T);for(cas=1;cas<=T;cas++){scanf("%d",&n);map<string,int>city;string name1,name2;for(i=1;i<=n;i++){cin>>name1;//一大坑点,输入的不是城市编号,是城市名,要用map巧妙地city[name1]=i;//将字符串的城市名转化为数值类型的城市编号  }scanf("%d",&m);init();while(m--){cin>>name1>>name2>>w;add(city[name1],city[name2],w);}int start=city["Calgary"];int ed=city["Fredericton"];spfa(start,ed);scanf("%d",&Q);printf("Scenario #%d\n",cas);while(Q--){scanf("%d",&s);s=min(s,n-2);//一大坑点!!!输入的可停留次数可能超出合法范围,必须自己做处理!!! ans=INF;for(i=0;i<=s;i++)ans=min(ans,dis[n][i+1]);if(ans>=INF){printf("No satisfactory flights\n");}else{printf("Total cost of flight(s) is $%d\n",ans);}}if(cas!=T){printf("\n");}}return 0; } 



0 0
原创粉丝点击