Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 39119 Accepted Submission(s): 11411
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
大致题意: 这就是中文题意自己看
解题思路:我是用Dijkstra + 邻接矩阵 正常情况下邻接矩阵存的值是从A到B的距离 这里我将矩阵开为结构体 同时存距离和花费 dis数组同样开结构体 对于任意两点的距离 将起点S初始化为0就能求S到T的最短距离
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#define met(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e3 + 10;
int vis[MAXN];
using namespace std;
struct node //邻接矩阵结构体
{
int len, cot;//长度 花费
}MAP[MAXN][MAXN];
struct disnode
{
int len, cot;
}dis[MAXN];
struct Dijkstra
{
void init()//初始化函数
{
met(vis, 0);
met(MAP, 0x3f);
met(dis, 0x3f);
return ;
}
void add(int a, int b, int d, int p)//加边
{
if (MAP[a][b].len > d)
{ MAP[a][b].len = d; MAP[a][b].cot = p; }
else if (MAP[a][b].len == d)
MAP[a][b].cot = min(MAP[a][b].cot, p);
MAP[b][a].len = MAP[a][b].len; //始终让MAP[a][b] == MAP[b][a]
MAP[b][a].cot = MAP[a][b].cot;
return ;
}
void dijkstra(int s, int n)//传入起点和总个数
{
dis[s].len = dis[s].cot = 0;
for (int i = 1; i < n; i++)
{
int k, minn = INF;
for (int j = 1; j <= n; j++)
{
if (!vis[j] && dis[j].len < minn)
{ k = j; minn = dis[j].len; }
}
vis[k] = 1;
for (int j = 1; j <= n; j++)
{
if (!vis[j] && dis[j].len > dis[k].len + MAP[k][j].len)//松弛操作 注意同时应更改距离和花费
{
dis[j].len = dis[k].len + MAP[k][j].len;
dis[j].cot = dis[k].cot + MAP[k][j].cot;
}
else if (!vis[j] && dis[j].len == dis[k].len + MAP[k][j].len)//距离相等改花费
{
if (dis[j].cot > dis[k].cot + MAP[k][j].cot)
dis[j].cot = dis[k].cot + MAP[k][j].cot;
}
}
}
return ;
}
}Dj;
int main()
{
int n, m;
while (~scanf("%d %d", &n, &m) && (n + m))
{
Dj.init();//初始化
for (int i = 0; i < m; i++)
{
int a, b, d, p;
scanf("%d %d %d %d", &a, &b, &d, &p);//输入两点以及长度,花费
Dj.add(a, b, d, p);
}
int s, t;
scanf("%d %d", &s, &t);//输入起点 终点
Dj.dijkstra(s, n);
printf("%d %d\n", dis[t].len, dis[t].cot);
}
return 0;
}