这一题学到的东西太多了
1.大数组不能开在函数中,要使用全局变量
2.bellman_ford算法
3.c语言中struct不能有构造函数,开数组不能使用const的值作为大小,而要用define.
4.代替vector的建图方法,数组模拟链表法,map[i]存第i个点的第一条边在e中的下标。e用来存边,next记录该点的下一条边的坐标。
5.使用vector的效率极低。
本题只需建正反两个图,分别求距离,把所有点的距离加起来就是答案。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int maxn = 1000000; struct Edge { int v, w, nxt; Edge() { } Edge(int vv, int ww, int nn) : v(vv), w(ww), nxt(nn) { } } e[maxn], ope[maxn]; int map[maxn], opmap[maxn]; int p, q; long long ans; long long dist[maxn]; void init() { ans = 0; scanf("%d%d", &p, &q); memset(map, -1, sizeof(map)); memset(opmap, -1, sizeof(opmap)); for (int i = 0; i < q; i++) { int a, b, w; scanf("%d%d%d", &a, &b, &w); a--; b--; e[i] = (Edge(b, w, map[a])); map[a] = i; ope[i] = (Edge(a, w, opmap[b])); opmap[b] = i; } } bool relax(long long *dist, int u, Edge &e) { if (dist[e.v] > dist[u] + e.w || dist[e.v] == -1) { dist[e.v] = dist[u] + e.w; return true; } return false; } void bellman(int *map, Edge *e) { int q[maxn], front = 0, rear = 1; bool vis[maxn]; memset(dist, -1, sizeof(dist)); memset(vis, 0, sizeof(vis)); q[0] = 0; dist[0] = 0; vis[0] = true; while (front != rear) { int temp = q[front++]; if (front == maxn) front = 0; vis[temp] = false; for (int i = map[temp]; i != -1; i = e[i].nxt) { if (relax(dist, temp, e[i]) && !vis[e[i].v]) { q[rear++] = e[i].v; if (rear == maxn) rear = 0; vis[e[i].v] = true; } } } for (int i = 0; i < p; i++) ans += dist[i]; } int main() { //freopen("D:\\t.txt", "r", stdin); int t; scanf("%d", &t); while (t--) { init(); bellman(map, e); bellman(opmap, ope); printf("%I64d\n", ans); } return 0; }