uva10246- Asterix and Obelix
题目大意及思路:
一个人从某个城市去另一个城市,在途经的某个城市(包括起点和终点)要请人吃饭,在每个城市吃饭的花费不同,在每个城市间行走所需费用也不同。现在他在旅途中吃饭最贵的城市请人吃饭,问总的花费最小是多少。
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到5花费最小的路径是1-2-3-5=20+10+10+ 5(1 2 3 5中吃饭最贵的城市为3,花5块钱)=45
解法:很明显的最短路径,但现在多了一个“要吃饭”的点要考虑,我们可以枚举吃饭的点,并求出每个点到吃饭点的距离,这里要注意,必须保证这条路上所有点的点权不得大于吃饭点的权值。最后按照询问的点直接计算即可
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #define INF 999999999 using namespace std; int host[100],g[100][100],vis[100],dis[100][100],crt[100]; void readcase(int r,int c){ for(int i=1;i<=r;i++){ scanf("%d",&host[i]); } for(int i=1;i<=c;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); g[x][y]=z; g[y][x]=z; } } int spfa(int s,int r){ memset(vis,0,sizeof(vis)); queue<int>que; while(!que.empty()){ que.pop(); } que.push(s); vis[s]=1; dis[s][s]=0; while(!que.empty()){ int now=que.front(); que.pop(); vis[now]=0; for(int i=1;i<=r;i++){ if(g[now][i] <INF&&dis[s][i]>dis[s][now]+g[now][i] && host[now]<=host[s] && host[i] <= host[s] ){ dis[s][i]=dis[s][now]+g[now][i]; if(vis[i]==0){ vis[i]=1; que.push(i); } } } } } void compute(int r,int q,int c){ for(int i=1;i<=q;i++){ int s,t; scanf("%d%d",&s,&t); int ans=INF; for(int i=1;i<=r;i++){ //cout<<dis[i][s]<<" "<<dis[i][t]<<endl; if(ans>dis[i][s]+dis[i][t]+host[i]){ ans=dis[i][s]+dis[i][t]+host[i]; } //cout<<ans<<endl; } if(ans<INF){ printf("%d\n",ans); } else{ printf("-1\n"); } } } int main() { int r,c,q; int counter=0; while(~scanf("%d%d%d",&r,&c,&q) && (r!=0 || c!=0 || q!=0)){ if(counter!=0){ printf("\n"); } counter++; printf("Case #%d\n",counter); memset(host,0,sizeof(host)); for(int i=1;i<=r;i++){ for(int j=1;j<=r;j++){ g[i][j]=INF; } } for(int i=1;i<=r;i++){ for(int j=1;j<=r;j++){ dis[i][j]=INF; } } readcase(r,c); for(int i=1;i<=r;i++){ spfa(i,r); //cout<<endl; } compute(r,q,c); } return 0; }