最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 25261 Accepted Submission(s): 7538
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2 1 2 5 6 2 3 4 5 1 3 0 0
Sample Output
9 11
Source
Recommend
notonlysuccess | We have carefully selected several similar problems for you:
2544
1874
2066
1217
2112
解题思路:
直接dij算,只不过当最短路长度一样的时候选择花费最小的那个就好了。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 10005 ;
const int INF = 0x3f3f3f3f ;
int n,m ;
struct Edge{
int from;
int to ;
int dist ;
int p ;
};
struct node{
int u,d ;
bool operator <(const node &p)const{
return d>p.d ;
}
};
vector<Edge> edges ;
vector<int>G[maxn] ;
bool done[maxn] ;
int d[maxn] ;
int pp[maxn] ;
void addEdge(int from,int to,int d,int p){
edges.push_back((Edge){from,to,d,p}) ;
int mm = edges.size() ;
G[from].push_back(mm-1) ;
}
void dij01(int s){
priority_queue<node>qq ;
for(int i=0;i<n;i++){d[i]=INF,pp[i]=INF ;}
d[s]=0 ;
pp[s]=0 ;
memset(done,false,sizeof(done)) ;
qq.push((node){s,0}) ;
while(!qq.empty()){
node x = qq.top() ;
//cout<<"qq=="<<x.u<<" "<<x.d<<endl ;
qq.pop() ;
int u = x.u ;
if(done[u])continue ;
done[u]=true ;
int len = G[u].size() ;
for(int i=0;i<len;i++){
Edge& e = edges[G[u][i]] ;
//printf("i=%d\n",i);
if(d[e.to]==d[u]+e.dist&&pp[e.to] > pp[u]+e.p){
pp[e.to] = pp[u]+e.p ;
}
if(d[e.to]>d[u]+e.dist){
d[e.to] = d[u]+e.dist ;
pp[e.to] = pp[u]+e.p ;
qq.push((node){e.to,d[e.to]}) ;
}
}
}
}
int main(){
while(~scanf("%d%d",&n,&m)){
edges.clear() ;
for(int i=0;i<n;i++)G[i].clear();
if(n+m==0)break ;
for(int i=0;i<m;i++){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d) ;
//cin>>a>>b>>c>>d ;
a--;
b--;
addEdge(a,b,c,d) ;
addEdge(b,a,c,d) ;
}
int s,t ;
//cin>>s>>t ;
scanf("%d%d",&s,&t);
s-- ;
t--;
dij01(s) ;
//cout<<d[t]<<" "<<pp[t]<<endl ;
printf("%d %d\n",d[t],pp[t]);
}
return 0;
}
/**
3 3
1 2 5 6
2 3 4 5
1 3 9 10
1 3
0 0
*/