您的位置:首页 > 其它

HDOJ 3790 最短路径问题(双关键字最短路)

2017-05-10 00:27 375 查看

最短路径问题

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

Total Submission(s): 26248    Accepted Submission(s): 7810


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

与最简单的最短路唯一区别就是多加了一个关键字,在松弛操作时多加一个判断条件即可

#include<bits/stdc++.h>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
#define ll long long
const int maxn = 1005;
const int mod = 475;
const int INF = 0x0fffffff;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
int c[maxn][maxn],cost[maxn][maxn];
int dis[maxn],w[maxn];
int n,m;

void Dijkstra(int v)
{
bool vis[maxn];
for(int i=0;i<n;i++)
{
dis[i]=c[v][i];
vis[i]=0;
w[i]=cost[v][i];
}
vis[v]=1;
for(int i=1;i<n;i++)
{
int tmp=INF;
int u=v;
for(int j=0;j<n;j++)
{
if(!vis[j]&&dis[j]<tmp)
{
u=j;
tmp=dis[j];
}
}
vis[u]=1;
for(int j=0;j<n;j++)
{
if(!vis[j]&&c[u][j]<INF)
{
int newdis=dis[u]+c[u][j];
if(newdis<dis[j])
{
dis[j]=newdis;
w[j]=w[u]+cost[u][j];
}
else if(newdis==dis[j]&&w[j]>w[u]+cost[u][j])
w[j]=w[u]+cost[u][j];
}
}
}
}

int main()
{
int a,b,x,p;
int s,t;
while(~scanf("%d%d",&n,&m)&&(n||m))
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i==j)
c[i][j]=cost[i][j]=0;
else c[i][j]=cost[i][j]=INF;
}
}
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&a,&b,&x,&p);
a--,b--;
if(x<c[a][b])
{
c[a][b]=c[b][a]=x;
cost[a][b]=cost[b][a]=p;
}
if(x==c[a][b]&&cost[a][b]>p)
cost[a][b]=cost[b][a]=p;
}
scanf("%d%d",&s,&t);
s--,t--;
Dijkstra(s);
printf("%d %d\n",dis[t],w[t]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: