这一题学到的东西太多了
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;
}