HDU-3790 最短路径问题(双重权值)

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)
 
Output
输出 一行有两个数, 最短距离及其花费。
 
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
 
题目解析:多一重权值,就加一重“dis数组”。
 
代码如下:
 # include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
# include<queue>
using namespace std;
const int INF=<<;
struct node
{
int v,l;
};
node mp[][];
int n,m,s,t;
int dis[],val[];
void spfa()
{
fill(dis,dis+n+,INF);
fill(val,val+n+,INF);
queue<int>q;
q.push(s);
dis[s]=val[s]=;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=;i<=n;++i){
if(dis[i]>dis[u]+mp[u][i].l){
dis[i]=dis[u]+mp[u][i].l;
val[i]=val[u]+mp[u][i].v;
q.push(i);
}else if(dis[i]==dis[u]+mp[u][i].l&&val[i]>val[u]+mp[u][i].v){
val[i]=val[u]+mp[u][i].v;
q.push(i);
}
}
}
printf("%d %d\n",dis[t],val[t]);
}
void init()
{
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
mp[i][j].l=mp[i][j].v=(i==j)?:INF;
}
int main()
{
int a,b,c,d;
while(scanf("%d%d",&n,&m),n+m)
{
init();
while(m--)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if(mp[a][b].l>c){
mp[a][b].l=mp[b][a].l=c;
mp[a][b].v=mp[b][a].v=d;
}else if(mp[a][b].l==c){
mp[a][b].v=mp[b][a].v=min(d,mp[a][b].v);
}
}
scanf("%d%d",&s,&t);
spfa();
}
return ;
}
上一篇:ASP.NET MVC 基于页面的权限管理


下一篇:Oracle从入门到精通 限定查询和排序查询的问题