题意:有向图,所有点先走到x点,在从x点返回,问其中最大的某点最短路程
分析:对图正反都跑一次最短路,开两个数组记录x到其余点的距离,这样就能求出来的最短路以及回去的最短路.
POJ 3268
//#include <bits/stdc++.h> #include <cstdio> #include <queue> #include <algorithm> #include <cstring> using namespace std; typedef long long ll; const int N = 1e6 + 5; const int E = N; const int INF = 0x3f3f3f3f; struct Edge { int u, v, w, nex; Edge() {} Edge(int u, int v, int w, int nex) : u (u), v (v), w (w), nex (nex) {} bool operator < (const Edge &r) const { return w > r.w; } }edge[2][E]; int head[N]; int d[2][N]; bool vis[N]; int n, m, x, e; inline int read(void) { int f = 1, ret = 0; char ch = getchar (); while (ch > ‘9‘ || ch < ‘0‘) { if (ch == ‘-‘) f = -1; ch = getchar (); } while (ch <= ‘9‘ && ch >= ‘0‘) { ret = ret * 10 + ch - ‘0‘; ch = getchar (); } return ret * f; } void init(void) { memset (head, -1, sizeof (head)); e = 0; } void add_edge(int u, int v, int w) { edge[0][e] = Edge (u, v, w, head[u]); head[u] = e++; } void build_re_graph(void) { memset (head, -1, sizeof (head)); e = 0; for (int i=0; i<m; ++i) { edge[1][e] = Edge (edge[0][i].v, edge[0][i].u, edge[0][i].w, head[edge[0][i].v]); head[edge[0][i].v] = e++; } } void SPFA(int s, int tp) { memset (d[tp], INF, sizeof (d[tp])); memset (vis, false, sizeof (vis)); d[tp][s] = 0; vis[s] = true; queue<int> que; que.push (s); while (!que.empty ()) { int u = que.front (); que.pop (); vis[u] = false; for (int i=head[u]; ~i; i=edge[tp][i].nex) { int v = edge[tp][i].v, w = edge[tp][i].w; if (d[tp][v] > d[tp][u] + w) { d[tp][v] = d[tp][u] + w; if (!vis[v]) { vis[v] = true; que.push (v); } } } } } void Dijkstra(int s, int tp) { memset (vis, false, sizeof (vis)); memset (d[tp], INF, sizeof (d[tp])); d[tp][s] = 0; priority_queue<Edge> que; que.push (Edge (0, s, d[tp][s], 0)); while (!que.empty ()) { int u = que.top ().v; que.pop (); if (vis[u]) continue; for (int i=head[u]; ~i; i=edge[tp][i].nex) { int v = edge[tp][i].v, w = edge[tp][i].w; if (!vis[v] && d[tp][v] > d[tp][u] + w) { d[tp][v] = d[tp][u] + w; que.push (Edge (0, v, d[tp][v], 0)); } } } } int get_max(void) { int ret = 0; for (int i=1; i<=n; ++i) { ret = max (ret, d[0][i] + d[1][i]); } return ret; } int main(void) { while (scanf ("%d%d%d", &n, &m, &x) == 3) { init (); for (int u, v, w, i=0; i<m; ++i) { scanf ("%d%d%d", &u, &v, &w); add_edge (u, v, w); } //SPFA (x, 0); Dijkstra (x, 0); build_re_graph (); //SPFA (x, 1); Dijkstra (x, 1); int ans = get_max (); printf ("%d\n", ans); } return 0; }
还有一道类似的题目,是求最大和,其实都是一样的
POJ 1511
//#include <bits/stdc++.h> #include <cstdio> #include <queue> #include <algorithm> #include <cstring> using namespace std; typedef long long ll; const int N = 1e6 + 5; const int E = N; const int INF = 0x3f3f3f3f; struct Edge { int u, v, w, nex; Edge() {} Edge(int u, int v, int w, int nex) : u (u), v (v), w (w), nex (nex) {} bool operator < (const Edge &r) const { return w > r.w; } }edge[2][E]; int head[N]; int d[N]; bool vis[N]; int n, m, e; inline int read(void) { int f = 1, ret = 0; char ch = getchar (); while (ch > ‘9‘ || ch < ‘0‘) { if (ch == ‘-‘) f = -1; ch = getchar (); } while (ch <= ‘9‘ && ch >= ‘0‘) { ret = ret * 10 + ch - ‘0‘; ch = getchar (); } return ret * f; } void init(void) { memset (head, -1, sizeof (head)); e = 0; } void add_edge(int u, int v, int w) { edge[0][e] = Edge (u, v, w, head[u]); head[u] = e++; } void build_re_graph(void) { memset (head, -1, sizeof (head)); e = 0; for (int i=0; i<m; ++i) { edge[1][e] = Edge (edge[0][i].v, edge[0][i].u, edge[0][i].w, head[edge[0][i].v]); head[edge[0][i].v] = e++; } } void SPFA(int s, int tp) { memset (d, INF, sizeof (d)); memset (vis, false, sizeof (vis)); d[s] = 0; vis[s] = true; queue<int> que; que.push (s); while (!que.empty ()) { int u = que.front (); que.pop (); vis[u] = false; for (int i=head[u]; ~i; i=edge[tp][i].nex) { int v = edge[tp][i].v, w = edge[tp][i].w; if (d[v] > d[u] + w) { d[v] = d[u] + w; if (!vis[v]) { vis[v] = true; que.push (v); } } } } } ll get_sum(void) { ll ret = 0; for (int i=1; i<=n; ++i) { ret += d[i]; } return ret; } int main(void) { int T; scanf ("%d", &T); while (T--) { scanf ("%d%d", &n, &m); init (); for (int u, v, w, i=0; i<m; ++i) { //scanf ("%d%d%d", &u, &v, &w); u = read (); v = read (); w = read (); add_edge (u, v, w); } SPFA (1, 0); ll ans = get_sum (); build_re_graph (); SPFA (1, 1); ans += get_sum (); printf ("%lld\n", ans); } return 0; }
时间: 2024-10-02 07:26:43