这段时间应该是要写最短路,生成树,lca和树的直径什么的。
ZOJ-1586
最小生成树,但是每条边的权值还要加上该边两端节点的权值。
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e6 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int s[10005]; int price[1005]; int mp[1005][1005]; struct Edge { int u, v, val; }edge[maxn]; bool cmp(Edge a, Edge b) { return a.val < b.val; } int get(int x) { if (x == s[x]) return x; return s[x] = get(s[x]); } int kru(int n, int m) { int ans = 0, cnt = 0; for (int i = 1; i <= n; i++) s[i] = i; sort(edge + 1, edge + 1 + m, cmp); for (int i = 1; i <= m; i++) { int x = get(edge[i].u); int y = get(edge[i].v); if (x == y) continue; s[x] = y; ans += edge[i].val; cnt++; if (cnt == n - 1) break; } return ans; } int main() { int t; scanf("%d", &t); while (t--) { memset(mp, 0, sizeof(mp)); int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &price[i]); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &mp[i][j]); } } int cnt = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i != j) { edge[++cnt].u = i; edge[cnt].v = j; edge[cnt].val = mp[i][j] + price[i] + price[j]; } } } int ans = kru(n, cnt); printf("%d ", ans); } return 0; }
HDU-2586
lca,倍增。树上两点的距离 d(x, y) = h(x) + h(y) - 2*h(lca(x, y))
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int tot = 0, t; int head[maxn], Next[maxn], edge[maxn], ver[maxn]; int f[maxn][30], d[maxn], dist[maxn]; void add(int x, int y, int z) { ver[++tot] = y; edge[tot] = z; Next[tot] = head[x]; head[x] = tot; } void bfs() { queue<int>qe; qe.push(1); d[1] = 1; while (qe.size()) { int x = qe.front(); qe.pop(); for (int i = head[x]; i; i = Next[i]) { int y = ver[i]; if (d[y]) continue; d[y] = d[x] + 1; dist[y] = dist[x] + edge[i]; f[y][0] = x; for (int j = 1; j <= t; j++) { f[y][j] = f[f[y][j - 1]][j - 1]; } qe.push(y); } } } int lca(int x, int y) { if (d[x] > d[y]) swap(x, y); for (int i = t; i >= 0; i--) { if (d[f[y][i]] >= d[x]) y = f[y][i]; } if (x == y) return x; for (int i = t; i >= 0; i--) { if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; } return f[x][0]; } int main() { int T; scanf("%d", &T); while (T--) { int n, m; scanf("%d %d", &n, &m); t = (int)(log(n) / log(2)) + 1; tot = 0; memset(head, 0, sizeof(head)); memset(d, 0, sizeof(d)); for (int i = 0; i < n - 1; i++) { int u, v, val; scanf("%d %d %d", &u, &v, &val); add(u, v, val); add(v, u, val); } bfs(); for (int i = 1; i <= m; i++) { int x, y; scanf("%d%d", &x, &y); printf("%d ", dist[x] + dist[y] - 2 * dist[lca(x, y)]); } } return 0; }
POJ-1986
lca
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int tot = 0, t; int head[maxn], Next[maxn], edge[maxn], ver[maxn]; int f[maxn][30], d[maxn], dist[maxn]; void add(int x, int y, int z) { ver[++tot] = y; edge[tot] = z; Next[tot] = head[x]; head[x] = tot; } void bfs() { queue<int>qe; qe.push(1); d[1] = 1; while (qe.size()) { int x = qe.front(); qe.pop(); for (int i = head[x]; i; i = Next[i]) { int y = ver[i]; if (d[y]) continue; d[y] = d[x] + 1; dist[y] = dist[x] + edge[i]; f[y][0] = x; for (int j = 1; j <= t; j++) { f[y][j] = f[f[y][j - 1]][j - 1]; } qe.push(y); } } } int lca(int x, int y) { if (d[x] > d[y]) swap(x, y); for (int i = t; i >= 0; i--) { if (d[f[y][i]] >= d[x]) y = f[y][i]; } if (x == y) return x; for (int i = t; i >= 0; i--) { if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; } return f[x][0]; } int main() { int n, m; scanf("%d %d", &n, &m); t = (int)(log(n) / log(2)) + 1; tot = 0; memset(head, 0, sizeof(head)); memset(d, 0, sizeof(d)); for (int i = 1; i <= m; i++) { int u, v, val; scanf("%d %d %d", &u, &v, &val); string s; cin >> s; add(u, v, val); add(v, u, val); } bfs(); int q; scanf("%d", &q); for (int i = 1; i <= q; i++) { int x, y; scanf("%d%d", &x, &y); printf("%d ", dist[x] + dist[y] - 2 * dist[lca(x, y)]); } return 0; }
POJ-1330
lca,这里的root不一定1
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int tot = 0, t; int head[maxn], Next[maxn], edge[maxn], ver[maxn]; int f[maxn][30], d[maxn], dist[maxn]; void add(int x, int y) { ver[++tot] = y; Next[tot] = head[x]; head[x] = tot; } void bfs(int root) { queue<int>qe; qe.push(root); d[root] = 1; while (qe.size()) { int x = qe.front(); qe.pop(); for (int i = head[x]; i; i = Next[i]) { int y = ver[i]; if (d[y]) continue; d[y] = d[x] + 1; f[y][0] = x; for (int j = 1; j <= t; j++) { f[y][j] = f[f[y][j - 1]][j - 1]; } qe.push(y); } } } int lca(int x, int y) { if (d[x] > d[y]) swap(x, y); for (int i = t; i >= 0; i--) { if (d[f[y][i]] >= d[x]) y = f[y][i]; } if (x == y) return x; for (int i = t; i >= 0; i--) { if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; } return f[x][0]; } int main() { int T; scanf("%d", &T); while (T--) { int n, m; scanf("%d", &n); t = (int)(log(n) / log(2)) + 1; tot = 0; memset(head, 0, sizeof(head)); memset(d, 0, sizeof(d)); int root = -1; for (int i = 1; i <= n - 1; i++) { int u, v; scanf("%d %d", &u, &v); if (root == -1) root = u; add(u, v); add(v, u); } bfs(root); int x, y; scanf("%d %d", &x, &y); printf("%d ", lca(x, y)); } return 0; }