Prim最小生成树模板题
代码#includePOJ - 1287 Networking 思路#include #include #include using namespace std; typedef long long LL; const int N = 200, M = N * N; int g[N][N]; int dist[N]; int n; bool st[N]; LL prim() { LL res = 0; memset(dist, 0x3f, sizeof dist); for (int i = 0; i < n; i ++) { int t = -1; for (int j = 0; j < n; j ++) { if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j; } if(i) res += dist[t]; st[t] = true; for (int j = 0; j < n; j ++) { dist[j] = min(dist[j], g[t][j]); } } return res; } int main() { ios::sync_with_stdio(false); cin.tie(0); while(cin >> n && n) { memset(g, 0x3f, sizeof g); memset(st, false, sizeof st); for (int i = 0; i < n - 1; i ++) { char A[2]; cin >> A; int a = A[0] - 'A'; int m; cin >> m; while(m --) { char B[2]; int c; cin >> B >> c; int b = B[0] - 'A'; g[a][b] = g[b][a] = min(g[a][b], c); } } LL ans = prim(); cout << ans << endl; } return 0; }
Prim模板
代码#includePOJ - 2421 Constructing Roads 题意#include #include using namespace std; typedef long long LL; const int N = 55; int g[N][N]; int dist[N]; bool st[N]; int n, m; LL prim() { LL res = 0; memset(dist, 0x3f, sizeof dist); for (int i = 0; i < n; i ++) { int t = -1; for (int j = 1; j <= n; j ++) { if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j; } if(i) res += dist[t]; st[t] = true; for (int j = 1; j <= n; j ++) { dist[j] = min(dist[j], g[t][j]); } } return res; } int main() { while(cin >> n >> m && n) { memset(g, 0x3f, sizeof g); memset(st, false, sizeof st); while(m --) { int a, b, c; cin >> a >> b >> c; g[a][b] = g[b][a] = min(g[a][b], c); } LL ans = prim(); cout << ans << endl; } return 0; }
第一部分输入边的信息
第二部分输入 一开始哪些边已经建好了
直接套Kruscal好写点
心得函数的重构学到了
(再也不怕不支持c++11了,c++11直接写大括号赋值)
#includePOJ - 2349 Arctic Network 题意#include #include using namespace std; const int N = 110, M = N * N; const int inf = 0x3f3f3f; typedef long long LL; struct Edge { int a, b, w; Edge(int aa, int bb, int ww) { a = aa, b = bb, w = ww; } Edge() { a = 0, b = 0, w = inf; } bool operator < (const Edge &W)const { return w < W.w; } }edges[M]; int p[N]; int cnt; int find(int x) { if(p[x] != x) p[x] = find(p[x]); return p[x]; } void init() { for (int i = 1; i < N; i ++) p[i] = i; cnt = 0; } LL Kruscal() { LL res = 0; sort(edges, edges + cnt); for (int i = 0; i < cnt; i ++) { int a = edges[i].a, b = edges[i].b, w = edges[i].w; int fa = find(a), fb = find(b); if(fa != fb) { res += w; p[fa] = fb; } } return res; } int main() { int n; cin >> n; init(); for (int i = 1; i <= n; i ++) for (int j = 1; j <= n; j ++) { int w; cin >> w; edges[cnt++] = Edge{i, j, w}; } int m; cin >> m; while(m --) { int a, b; cin >> a >> b; int fa = find(a), fb = find(b); if(fa != fb) p[fa] = fb; } LL ans = Kruscal(); cout << ans << endl; return 0; }
给出k个卫星, 求最小的D使得村庄的连接都能连通
k个卫星的作用:可以删除最小生成树中k-1条边
D就是删边之后最小生成树中最大的边
也挺简单,就是求Kruscal记录边的权值,输出w[m-k-1]即可
代码#include#include #include #include #include #define x first #define y second using namespace std; typedef pair PII; const int N = 510, M = N * N; int k, m; PII point[M]; int cnt1; int cnt2; double weight[M]; int p[N]; struct Edge { int a, b; double w; Edge(int aa, int bb, double ww) { a = aa, b = bb, w = ww; } Edge() { a = 0, b = 0, w = 0; } bool operator < (const Edge& W)const { return w < W.w; } } edges[M]; void init() { cnt1 = cnt2 = 0; for (int i = 0; i < N; i ++) p[i] = i; } int find(int x) { if(p[x] != x) return p[x] = find(p[x]); return p[x]; } double get_dis(int x1, int y1, int x2, int y2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } double Kruscal() { sort(edges, edges + cnt1); for (int i = 0; i < cnt1; i ++) { int a = edges[i].a, b = edges[i].b; double dis = edges[i].w; int fa = find(a), fb = find(b); if(fa != fb) { weight[cnt2++] = dis; p[fa] = fb; } } return weight[m - k - 1]; } int main() { int T; scanf("%d", &T); while(T --) { init(); scanf("%d%d", &k, &m); for (int i = 0; i < m; i ++) { int x, y; scanf("%d%d", &point[i].x, &point[i].y); } for (int i = 0; i < m; i ++) for (int j = i + 1; j < m; j ++) { double dis = get_dis(point[i].x, point[i].y, point[j].x, point[j].y); edges[cnt1++] = Edge{i, j, dis}; } double ans = Kruscal(); printf("%.2fn", ans); } return 0; }



