Time Limit: 1000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
6 2 31 3 51 4 72 8 123 8 44 9 129 10 21 28 9 10
9
邻接表建图,O(ElogV)代码:
/*0ms,304KB*/ #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<utility> #include<functional> #include<algorithm> using namespace std; const int mx = 1005; typedef pair<int, int> P; ///first是最短时间,second是顶点编号 struct edge { int cost, to; edge(int cost = 0, int to = 0) : cost(cost), to(to) {} } e; vector<edge> G[mx]; int disTo[mx]; priority_queue<P, vector<P>, greater<P> > pq; void dj(int s) { P p; edge e; int v, i; memset(disTo, 0x3f, sizeof(disTo)); disTo[s] = 0.0; while (!pq.empty()) pq.pop(); pq.push(P(0.0, s)); while (!pq.empty()) { p = pq.top(), pq.pop(); v = p.second; ///v视作e.from if (disTo[v] < p.first) continue; for (i = 0; i < G[v].size(); ++i) { e = G[v][i]; if (disTo[e.to] > disTo[v] + e.cost) ///v视作e.from { disTo[e.to] = disTo[v] + e.cost; pq.push(P(disTo[e.to], e.to)); } } } } int main() { int m, s, d, i, n, a, b, t, x; while (~scanf("%d%d%d", &m, &s, &d)) { for (i = 0; i < mx; ++i) G[i].clear(); n = 0; while (m--) { scanf("%d%d%d", &a, &b, &t); G[a].push_back(edge(t, b)); G[b].push_back(edge(t, a)); n = max(n, max(a, b)); } ++n;///城市数 while (s--) { scanf("%d", &x); G[0].push_back(edge(0, x)); ///超级源点 } while (d--) { scanf("%d", &x); G[x].push_back(edge(0, n)); ///超级汇点 } dj(0); printf("%d\n", disTo[n]); } return 0; }
邻接矩阵建图,O(V^2)代码:
/*31ms,4156KB*/ #include <cstdio> #include <cstring> using namespace std; const int maxn = 1002, INF = 1000000000; int t, s, d, a[maxn][maxn], i, j, n, temp; bool vis[maxn]; inline void init() { int x, y, z; for (i = 0; i < maxn; i++) for (j = 0; j < maxn; j++) a[i][j] = INF; n = 0; while (t--) { scanf("%d%d%d", &x, &y, &z); if (z < a[x][y]) a[y][x] = a[x][y] = z; if (x > n) n = x; if (y > n) n = y; } ++n;//城市数 for (i = 1; i <= s; i++) { scanf("%d", &x);//相邻点置为0 a[0][x] = 0; } for (i = 1; i <= d; i++) { scanf("%d", &x); a[x][n] = 0;//小技巧,相当于改变了把多个目标化为一个 } } inline void dijkstra() { int min, p; memset(vis, 0, sizeof(vis)); for (j = 1; j <= n; j++) { min = INF; for (i = 1; i <= n; i++) if (a[0][i] < min && !vis[i]) { min = a[0][i]; p = i;//标记最小值 } vis[p] = true; for (i = 1; i <= n; i++) { temp = a[0][p] + a[p][i]; if (temp < a[0][i]) a[0][i] = temp; } } } int main() { while (~scanf("%d%d%d", &t, &s, &d)) { init(); dijkstra(); printf("%d\n", a[0][n]); } return 0; }