hdu 3790
给你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
入门迪杰斯特拉 单源最短路问题
本人不会绘图以上图片来自网络
1 :初始化,开每个元素都是无限大的map【i】【j】,cost [i][j]图(数组),i,j;代表结点(就像图中的字母),cost的值代表价值,map的价值代表距离;然后输入元素;进行算法;
详细在代码中介绍;
时间有限,以后再填充;
代码详解
友情提示非纯c++有超时点;后面会标记;
//先让我bb几句,他喵的好累,好楼,思路这么简单的代码,还花这么长时间,还在以前不是很理解的情况下打过几边,
//幸运的是我现在已经了解他的每一个私处,卧槽,怎么快变成色情小说了,//滑稽;
//源码看一个小时,写出来,一个小时,找错误,一个小时,重新写,30min,找错误一个小时
//希望大家可以认真学习这个算法,如果你很聪明请例外,我这么low,只有多理解了,先之后每天打一边,一个月后我才能向你保证我可以流畅的使用迪杰斯特拉了。
i,j代表接结点(就是连接点)
flag【】代表状态,//这个是单源问题,不能重复走
#include<stdio.h>
#include<string.h>
int i, j, n, m, a, b, d, p;
#define inf 999999
int map[1001][1001], cost[1001][1001];
int flag[1001], value[1001], dis[1001];
void DJ(int st, int en)
{
for (i = 1; i <= n; i++)
{
dis[i] = map[st][i];
value[i] = cost[st][i];
}//初始化头节点,
memset(flag, 0, sizeof(flag));//初始化状态
flag[st] = 1;//头节点标记为1 ,不能再便利到他;
int v;
//在循环中的主要是实现没走和走之后的状态,综合贪心和dp思想;
for (i = 1; i <= n; i++)
{
int MIN = inf;//这个很重要//
for (j = 1; j <= n; j++)
{
if (!flag[j] && MIN > dis[j])
{
v = j;
MIN = dis[j];
}
}//找到1,2节点之间的最短距离;
flag[v] = 1;//标记
if (MIN == inf) break;
for (j = 1; j <= n; j++)
{
if (!flag[j] && map[v][j] < inf)//这个点没被查找过,且节点之间是可以走的
{
if (!flag[j] && dis[j] > map[v][j] + dis[v])//最关键,在第一次循环时dis【j】的值是inf,
//可以把他看作一个最大值,用它来遍历求得最小值
{
dis[j] = map[v][j] + dis[v];
value[j] = value[v] + cost[v][j];
}//保存数据
else if (dis[j] == map[v][j] + dis[v] && value[j] > value[v] + cost[v][j])
value[j] = value[v] + cost[v][j];//保存最小价值;
}
}
}
printf("%d %d\n", dis[en], value[en]);
}
int main()
{
while (~scanf("%d%d", &n, &m) && (n || m))
{
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
{
map[i][j] = inf;
cost[i][j] = inf;
}//不用memset初始化,那个没这个快;
while (m--)
{
scanf("%d%d%d%d", &a, &b, &d, &p);
if (map[a][b] > d || (map[a][b] == d && cost[a][b] > p))//存图,在节点之间有联系的情况记录下
{
map[a][b] = map[b][a] = d;
cost[a][b] = cost[b][a] = p;
}
}
int ss, ee;
scanf("%d%d", &ss, &ee);
DJ(ss, ee);
}
return 0;
}