Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7410 | Accepted: 4035 |
Description
Input
Output
Sample Input
1 0 2 3 1 2 37 2 1 17 1 2 68 3 7 1 2 19 2 3 11 3 1 7 1 3 5 2 3 89 3 1 91 1 2 32 5 7 1 2 5 2 3 7 2 4 8 4 5 11 3 5 10 1 5 6 4 2 12 0
Sample Output
0 17 1626
最小生成树裸题,今天整理模板。写了一发kruskal和一发prime。
AC代码:
kruskal
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 55 #define MAXM 3000 #define INF 0x3f3f3f3f using namespace std; struct Edge { int from, to, val; }; Edge edge[MAXM]; int pre[MAXN]; int N, M; bool cmp(Edge a, Edge b) { return a.val < b.val; } void init() { for(int i = 1; i <= N; i++) pre[i] = i; } void getMap() { int a, b, c; for(int i = 0; i < M; i++) { scanf("%d%d%d", &a, &b, &c); edge[i].from = a; edge[i].to = b; edge[i].val = c; } } int find(int p) { int t; int child = p; while(p != pre[p]) p = pre[p]; while(child != p) { t = pre[child]; pre[child] = p; child = t; } return p; } void merge(int x, int y) { int fx = find(x); int fy = find(y); if(fx != fy) pre[fx] = fy; } void solve() { sort(edge, edge+M, cmp); int ans = 0; for(int i = 0; i < M; i++) { if(find(edge[i].from) != find(edge[i].to)) ans += edge[i].val, merge(edge[i].from, edge[i].to); } printf("%d\n", ans); } int main() { while(scanf("%d", &N), N) { scanf("%d", &M); init(); getMap(); solve(); } return 0; }prime:
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 60 #define INF 0x3f3f3f3f using namespace std; int Map[MAXN][MAXN]; int N, M; void init() { for(int i = 1; i <= N; i++) { Map[i][i] = 0; for(int j = i+1; j <= N; j++) Map[i][j] = Map[j][i] = INF; } } void getMap() { int a, b, c; for(int i = 0; i < M; i++) { scanf("%d%d%d", &a, &b, &c); if(Map[a][b] > c) Map[a][b] = Map[b][a] = c; } } int dist[MAXN], low[MAXN]; bool vis[MAXN]; void prime() { int ans = 0; int next, Min; for(int i = 1; i <= N; i++) { low[i] = Map[1][i]; vis[i] = false; } vis[1] = true; for(int i = 2; i <= N; i++) { next = 1; Min = INF; for(int j = 1; j <= N; j++) { if(!vis[j] && Min > low[j]) { Min = low[j]; next= j; } } vis[next] = true; ans += Min; //if(Min == INF) //最小生成树不存在 for(int j = 1; j <= N; j++) { if(!vis[j] && low[j] > Map[next][j]) low[j] = Map[next][j]; } } printf("%d\n", ans); } int main() { while(scanf("%d", &N), N) { scanf("%d", &M); init(); getMap(); prime(); } return 0; }