您的位置:首页 > 其它

HDU 3790 最短路径问题【多关键字最短路,Dijkstra算法+spfa算法】

2016-07-26 15:33 405 查看


最短路径问题

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 22410 Accepted Submission(s): 6688



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


Source

浙大计算机研究生复试上机考试-2010年

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790

注意:最短路径长度相同的时候要输出花费最少的,松弛操作的时候要注意。

要注意此题有重边!!cin TLE


Dijkstra 算法AC代码:

#include <iostream>
#include <cstdio>
using namespace std;
int a[1005][1005];
int b[1005][1005];
int dis[1005];
int pay[1005];
bool vis[1005];
const int INF=0x3f3f3f3f;
int n,m,s,t;

void Dij()
{
for(int i=1; i<=n; i++)
{
dis[i]=a[s][i];
pay[i]=b[s][i];
vis[i]=false;
}
vis[s]=true;
dis[s]=pay[s]=0;
for(int i=1; i<=n; i++)
{
int minn=INF;
int p;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&(dis[j]<minn))
{
minn=dis[p=j];
}
}
vis[p]=true;
if(minn==INF) break;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&a[p][j]!=INF)
{
int t=dis[p]+a[p][j];
if(t<dis[j])
{
dis[j]=t;
pay[j]=pay[p]+b[p][j];
}
else if(t==dis[j]&&pay[p]+b[p][j]<pay[j])
{
pay[j]=pay[p]+b[p][j];
}
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF,n,m)
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
if(i==j) a[i][j]=b[i][j]=0;
else a[i][j]=b[i][j]=INF;
}
int x,y,z,zz;
while(m--)
{
scanf("%d%d%d%d",&x,&y,&z,&zz);
if(z<a[x][y])
{
a[x][y]=a[y][x]=z;
b[x][y]=b[y][x]=zz;
}
}
cin>>s>>t;
Dij();
cout<<dis[t]<<" "<<pay[t]<<endl;

}
return 0;
}


spfa算法AC代码:

#include <cstdio>
#include <queue>
using namespace std;
int a[1005][1005];
int b[1005][1005];
int dis[1005];
int pay[1005];
bool vis[1005];
int n,m,s,t;
const int INF=0x3f3f3f3f;
void spfa()
{
for(int i=1;i<=n;i++)
{
dis[i]=INF;
pay[i]=INF;
vis[i]=false;
}
vis[s]=true;
dis[s]=pay[s]=0;
queue<int>q;
q.push(s);
vis[s]=true;
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=false;
for(int i=1;i<=n;i++)
{
int d=dis[now]+a[now][i];
if(d<dis[i])
{
dis[i]=d;
pay[i]=pay[now]+b[now][i];
if(!vis[i])
{
vis[i]=true;
q.push(i);
}
}
else if(d==dis[i]&&pay[now]+b[now][i]<pay[i])
{
pay[i]=pay[now]+b[now][i];
if(!vis[i])
{
vis[i]=true;
q.push(i);
}
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF,n,m)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(i==j) a[i][j]=b[i][j]=0;
else a[i][j]=b[i][j]=INF;
}
int x,y,z,zz;
while(m--)
{
scanf("%d%d%d%d",&x,&y,&z,&zz);
if(a[x][y]>z)
{
a[x][y]=a[y][x]=z;
b[x][y]=b[y][x]=zz;
}
}
scanf("%d%d",&s,&t);
spfa();
printf("%d %d\n",dis[t],pay[t]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: