日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

逛街 最短距离+花费

發布時間:2024/10/6 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 逛街 最短距离+花费 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

逛街

時間限制: 1 Sec 內存限制: 128 MB

題目描述

假設渣渣灰有一個女朋友,他的女朋友要他陪著一起去公園。由于渣渣灰不喜歡運動,所以他想找一條最短的路到達公園。由于途中會有許多消費點,而每到一個消費點女朋友就要購物,而渣渣灰比較摳,所以假如有多條最短路,則他會選擇途中消費點最便宜的。給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s,終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。

輸入

輸入nm,點的編號是1~n然后是m行,每行4個數 abdp,表示a和b之間有一條邊,且其長度為d,花費為p。最后一行是兩個數 st;起點s,終點。n和m為0時輸入結束。
(1<n<=1000 0<m<100000 s != t)

輸出

輸出 一行有兩個數, 最短距離及其花費。

樣例輸入

2 2
1 2 5 10
2 1 4 12
1 2

4 4
1 2 5 6
2 3 4 5
1 4 5 10
4 3 4 2
1 3

6 7
1 2 5 6
1 3 5 1
2 6 2 1
3 4 1 1
4 2 1 1
4 5 1 1
5 2 3 1
5 6

0 0

樣例輸出

4 12
9 11
4 3

提示

輸入樣例的空行只是為了讓大家分辨數據,輸入有沒有空行都沒關系。輸出樣例沒有空行。

題解

dijkstra算法求單源最短路簡單擴展,我們再創建一個value數組儲存花費情況。在松弛時對value進行改變。

松弛成功則value(s->i)=value(s->k->i)。

若最短路相等則對value值進行比較,即value(s->i)=min(value(s->k->i),value(s->i))。

s為源點,i為當前終點,k為中間點。最終輸出最短路及對應value值即可。

#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int maxn=1e3+10; int n,m; struct node {int ds,cs; }road[maxn][maxn]; int dis[maxn];//最短距離 bool vis[maxn]; int cost[maxn];//花費 void dijkstra(int s) {memset(vis,0,sizeof(vis));memset(dis,inf,sizeof(dis));memset(cost,inf,sizeof(cost));dis[s]=0;cost[s]=0;vis[s]=1;for(int i=1;i<=n;i++)dis[i]=road[s][i].ds;for(int i=1;i<=n;i++){cost[i]=road[s][i].cs;//printf("%d:%d\n",i,dis[i]);}for(int u=1;u<n;u++){int minD=inf,k=-1;for(int i=1;i<=n;i++){if(!vis[i]&&dis[i]<minD){k=i;minD=dis[i];}}vis[k]=1;for(int i=1;i<=n;i++){if(!vis[i]&&dis[k]+road[k][i].ds<dis[i]){dis[i]=dis[k]+road[k][i].ds;cost[i]=cost[k]+road[k][i].cs;}//ifif(!vis[i]&&dis[k]+road[k][i].ds==dis[i]&&cost[i]>cost[k]+road[k][i].cs){cost[i]=cost[k]+road[k][i].cs;}//if}//for} } int main() {while(scanf("%d%d",&n,&m)&&n&&m){memset(road,inf,sizeof(road));for(int i=1;i<=m;i++){int a,b,d,p;scanf("%d%d%d%d",&a,&b,&d,&p);if(d<=road[a][b].ds)//處理路徑距離{if(d==road[a][b].ds)//如果距離相等,存放最短的花費road[a][b].cs=road[b][a].cs=min(p,road[a][b].cs);else //存放新路徑的費用road[a][b].cs=road[b][a].cs=p;road[a][b].ds=road[b][a].ds=d;//填充路徑}}int s,t;scanf("%d%d",&s,&t);dijkstra(s);printf("%d %d\n",dis[t],cost[t]);}return 0; } #include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f #define Min(a,b) a>b?b:a struct Node {int adj,val; }g[1005][1005]; int dist[1005];//距離 int value[1005];//費用 int used[1005];//標記 int n,m,i,j; void Dijkstra(int s) {memset(dist,0x3f,sizeof(dist));memset(value,0x3f,sizeof(value));memset(used,0,sizeof(used));dist[s]=0;//從起點開始value[s]=0;while(1){int k,u=-1,d[1005];int min=INF;memset(d,0,sizeof(d));for(i=1;i<=n;i++)if(used[i]==0&&dist[i]<min)//找出從起點到下一個最小距離的頂點{min=dist[i];//記錄最小值u=i;//記錄下標}if(u==-1)//判斷所有頂點是否都到達過return ;for(i=1,k=0;i<=n;i++)if(dist[u]==dist[i]&&used[i]==0)d[k++]=i;//從起點到下一個要訪問的頂點的最小距離可能有多個for(i=0;i<k;i++)used[d[i]]=1;for(i=0;i<k;i++)//多個滿足的點分別進行迪杰斯特拉最短路查找for(j=1;j<=n;j++)if(g[d[i]][j].adj!=INF && (dist[d[i]]+g[d[i]][j].adj)<=dist[j]){//原理與 main()函數中建立鄰接矩陣一樣if((dist[d[i]]+g[d[i]][j].adj)<dist[j])//小于的情況value[j]=value[d[i]]+g[d[i]][j].val;elsevalue[j]=Min(value[j],value[d[i]]+g[d[i]][j].val);dist[j]=dist[d[i]]+g[d[i]][j].adj;}} } int main() {while(scanf("%d%d",&n,&m) && (n||m)){int a,b,d,p;memset(g,0x3f,sizeof(g));for(i=1;i<=m;i++){scanf("%d%d%d%d",&a,&b,&d,&p);if(d<=g[a][b].adj)//處理路徑距離問題{if(d==g[a][b].adj)//如果距離相等,則存放最少的費用g[a][b].val=g[b][a].val=Min(p,g[a][b].val);else//否則,存放新路徑距離的費用g[a][b].val=g[b][a].val=p;g[a][b].adj=g[b][a].adj=d;//填充路徑距離}}int s,t;scanf("%d%d",&s,&t);Dijkstra(s);printf("%d %d\n",dist[t],value[t]);}return 0; }

?

總結

以上是生活随笔為你收集整理的逛街 最短距离+花费的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。