好久没写最短路了,这题刚开始没啥思路,网上搜了搜,光用Dijkstra求最短路是不够的,附上关键思路:
用dijkstra求出最短路径,遍历所有的边,若| dist[i] - dist[j] | < weight[i..j] ,这时候是从中间结束的。知道了这个之后就好写了。。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include<math.h>
struct Edge
{
int u, v, d;
};
static int n, m;
static int map[500][500], d[500], known[500];
static void dijkstra()
{
int i;
for (i = 1; i <= n; i++)
d[i] = INT_MAX;
memset(known, 0, sizeof(known));
d[1] = 0;
int now = 1, next, finish = 0;
while (!finish)
{
known[now] = 1;
int mind = INT_MAX;
finish = 1;
for (i = 1; i <= n; i++)
{
if (map[now][i] != -1 && !known[i] && d[now] + map[now][i] < d[i])
d[i] = d[now] + map[now][i];
if (!known[i] && d[i] < mind)
{
finish = 0;
mind = d[i];
next = i;
}
}
now = next;
}
}
int main()
{
struct Edge *array = malloc(500 * sizeof(struct Edge));
int count = 1;
while (scanf("%d %d", &n, &m), n || m)
{
printf("System #%d\n", count++);
int i, u, v, dis;
memset(map, -1, sizeof(map));
for (i = 0; i < m; i++)
{
scanf("%d %d %d", &u, &v, &dis);
map[u][v] = map[v][u] = dis;
array[i].u = u;
array[i].v = v;
array[i].d = dis;
}
dijkstra();
double maxt = 0;
int res = 1, ru = 0, rv = 0;
for (i = 1; i <= n; i++)
if (d[i] > maxt)
{
maxt = d[i];
res = i;
}
for (i = 0; i < m; i++)
if (abs(d[array[i].u] - d[array[i].v]) < array[i].d)
{
double dd = (array[i].d - abs(d[array[i].u] - d[array[i].v]))
/ 2.0;
dd += d[array[i].u] > d[array[i].v] ?
d[array[i].u] : d[array[i].v];
if (dd > maxt)
{
maxt = dd;
ru = array[i].u;
rv = array[i].v;
}
}
if (ru)
printf(
"The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n\n",
maxt, ru, rv);
else
printf(
"The last domino falls after %.1lf seconds, at key domino %d.\n\n",
maxt, res);
}
free(array);
return 0;
}