问题描述
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
输入格式
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
-2
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。
今天犯了几个十分低级的错误。
在双重循环里面用了同一个循环变量。
在开始用堆做这个题的时候卡了一会,不知道如何在堆中能直接索引元素,后来想到堆中只放数组下标,然后问题基本解决。
之后就是痛苦的Debug过程,因为堆中只有数组下标,所以堆排序的操作复杂到必然出错,结果花了几个小时才理清头绪。
又学了一遍堆排序,但总是记不住,不知道还要学几次。。。
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #define N 20020
- #define INF 2147483640
- typedef struct Node
- {
- int v;
- int d;
- struct Node *next;
- } Node, *Np;
- Np list[N];
- void insert(int a, int b, int c)
- {
- Np np = malloc(sizeof(Node));
- np->d = b;
- np->v = c;
- np->next = list[a];
- list[a] = np;
- }
- typedef struct Data
- {
- int v;
- int rp;
- }Data;
- Data data[N];
- int heap[N];
- void swap(int a, int b)
- {
- int t = heap[a];
- heap[a] = heap[b];
- heap[b] = t;
- data[heap[a]].rp = a;
- data[heap[b]].rp = b;
- }
- void up(int x)
- {
- while(x > 1)
- {
- if(data[heap[x / 2]].v > data[heap[x]].v)
- {
- swap(x, x / 2);
- x /= 2;
- }
- else
- {
- break;
- }
- }
- }
- void down(int x, int len)
- {
- while(x * 2 <= len)
- {
- int a = x * 2;
- if(a + 1 <= len && data[heap[a]].v > data[heap[a + 1]].v)
- {
- a = a + 1;
- }
- if(data[heap[x]].v > data[heap[a]].v)
- {
- swap(x, a);
- x = a;
- }
- else
- {
- break;
- }
- }
- }
- int main(void)
- {
- int i, n, m;
- scanf("%d%d", &n, &m);
- for(i = 0; i < m; i++)
- {
- int a, b, c;
- scanf("%d%d%d", &a, &b, &c);
- insert(a, b, c);
- }
- for(i = 2; i <= n; i++)
- {
- heap[i - 1] = i;
- data[i].v = INF;
- data[i].rp = i - 1;
- }
- Np p = list[1];
- while(p != NULL)
- {
- data[p->d].v = p->v;
- up(data[p->d].rp);
- p = p->next;
- }
- int count = n - 1;
- while(count > 1)
- {
- int base = heap[1];
- swap(1, count--);
- down(1, count);
- Np p = list[base];
- while(p != NULL)
- {
- int t = p->v + data[base].v;
- if(t < data[p->d].v)
- {
- data[p->d].v = t;
- up(data[p->d].rp);
- }
- Np temp = p;
- p = p->next;
- free(temp);
- }
- }
- for(i = 2; i <= n; i++)
- {
- printf("%d\n", data[i].v);
- }
- return 0;
- }