POJ 1511 最短路

链接:

http://poj.org/problem?id=1511

题意:

给你一个有向图,输出从0到所有点的距离总和+从所有点到0的距离总和的最小值

题解:

先正向建图,求一个最短路,再反向建图,求一个最短路,一定要用spfa,dijkstra会超时

代码:

31 #define inf 1000000000000LL
32 struct Node { int u, v; ll c; };
33 Node p[MAXN];
34 int head[MAXN], next[MAXN];
35 ll d[MAXN];
36 bool used[MAXN];
37 int now[MAXN];
38 int e, top, n, m;
39 
40 void add_node(int u, int v, ll c) {
41     p[e] = Node{ u,v,c };
42     next[e] = head[u]; head[u] = e++;
43 }
44 
45 bool relax(int u, int v, ll c) {
46     if (d[v]>d[u] + c) {
47         d[v] = d[u] + c;
48         return true;
49     }
50     return false;
51 }
52 
53 void spfa(int t) {
54     memset(used, 0, sizeof(used));
55     rep(i, 1, n + 1) d[i] = inf;
56     d[t] = 0, used[t] = 1, top = 0;
57     now[top++] = t;
58     while (top) {
59         int pre = now[--top];
60         used[pre] = 0;
61         for (int j = head[pre]; j + 1; j = next[j]) {
62             if (relax(p[j].u, p[j].v, p[j].c) && used[p[j].v] == false) {
63                 now[top++] = p[j].v;
64                 used[p[j].v] = true;
65             }
66         }
67     }
68 }
69 
70 int main() {
71     int T;
72     cin >> T;
73     while (T--) {
74         cin >> n >> m;
75         memset(head, -1, sizeof(head));
76         memset(next, -1, sizeof(next));
77         e = 0;
78         rep(i, 0, m) {
79             int u, v;
80             ll c;
81             scanf("%d%d%lld", &u, &v, &c);
82             add_node(u, v, c);
83         }
84         ll ans = 0;
85         spfa(1);
86         rep(i, 1, n + 1) ans += d[i];
87         memset(head, -1, sizeof(head));
88         memset(next, -1, sizeof(next));
89         e = 0;
90         rep(i, 0, m) add_node(p[i].v, p[i].u, p[i].c);
91         spfa(1);
92         rep(i, 1, n + 1) ans += d[i];
93         cout << ans << endl;
94     }
95     return 0;
96 }

 

posted @ 2017-04-30 00:13  Flowersea  阅读(202)  评论(0编辑  收藏  举报