九度:題目1008:最短路徑問題
阿新 • • 發佈:2019-01-27
- 題目描述:
- 給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。
- 輸入:
-
輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t;起點s,終點t。n和m為0時輸入結束。
(1<n<=1000, 0<m<100000, s != t)
- 輸出:
- 輸出 一行有兩個數, 最短距離及其花費。
- 樣例輸入:
-
3 2 1 2 5 6 2 3 4 5 1 3 0 0
- 樣例輸出:
-
9 11
乍一看像是dijkstra演算法,但是還多了一個求最少花費的條件,所以不能找到目標點就返回,必須將所有能到目標點的情況都要遍歷到,所以用SPFA演算法
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string> #include <queue> using namespace std; #define MAX 1002 #define INT 0x7fffffff int w[MAX]; int cost[MAX]; bool vis[MAX]; struct node{ int w,cost; }map[MAX][MAX]; int n,m,a,b,d,p,s,t; void SPFA(){ for(int i=1;i<=n;i++){w[i]=INT;cost[i]=INT;vis[i]=false;} queue<int> q; q.push(s); w[s]=0; cost[s]=0; vis[s]=true; while(!q.empty()){ int cur=q.front();q.pop(); vis[cur]=false; for(int i=1;i<=n;i++){ if(map[cur][i].w!=INT&&w[i]>=w[cur]+map[cur][i].w){ w[i]=w[cur]+map[cur][i].w; cost[i]=min(cost[i],cost[cur]+map[cur][i].cost); if(!vis[i]){ vis[i]=true; q.push(i); } } } } } int main(){ //freopen("C:\\in.txt","r",stdin); while(~scanf("%d%d",&n,&m)){ if(!n&&!m)break; for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){map[i][j].w=INT;map[i][j].cost=INT;} for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&a,&b,&d,&p); map[a][b].w=map[b][a].w=d; map[a][b].cost=map[b][a].cost=p; } scanf("%d%d",&s,&t); SPFA(); printf("%d %d\n",w[t],cost[t]); } return 0; } /************************************************************** Problem: 1008 User: starcuan Language: C++ Result: Accepted Time:10 ms Memory:9376 kb ****************************************************************/