模板题 Kruskal直接过 调试时候居然在sort(edge + 1, edge + 1 + m)上浪费好多时间...
不过本着ACMer的心态自然要测试一下两种方法分别的速度
Kruskal : Memory 392 Time 16
Prim: Memory 576 Time 16
...........哦居然一样啊
Prim
#include <cstdio> #include <cstring> #include <queue> #include <vector> #include <algorithm> #define INF 0x3F3F3F3F using namespace std; typedef pair<int, int> pii; struct cmp{ bool operator() (const pii a, const pii b){ return a.first > b.first; } }; int size, head[30], point[200], nxt[200], val[200]; int n, dist[30]; void init() { size = 0; memset(head, -1 ,sizeof head); } void add(int from, int to, int value) { val[size] = value; point[size] = to; nxt[size] = head[from]; head[from] = size++; } int prim(int s) { int ans = 0; bool vis[30]; memset(dist, 0x3f, sizeof dist); memset(vis, false, sizeof vis); priority_queue<pii, vector<pii>, cmp> q; for(int i = head[s]; ~i; i = nxt[i]){ dist[point[i]] = val[i]; q.push(make_pair(val[i], point[i])); } dist[s] = 0; vis[s] = true; while(!q.empty()){ pii u = q.top(); q.pop(); if(vis[u.second]) continue; vis[u.second] = true; ans += u.first; for(int i = head[u.second]; ~i; i = nxt[i]){ int j = point[i]; //printf("check edge[%d][%d] vis = %d value = %d ", u.second, j, vis[j], val[i]); if(!vis[j] && dist[j] > val[i]){ //printf("add edge[%d][%d] ", u.second, j); dist[j] = val[i]; q.push(make_pair(dist[j], j)); } } } return ans; } int main() { while(scanf("%d", &n), n){ init(); for(int i = 1; i < n; i++){ int k; scanf("%*s%d", &k); while(k--){ char to[2]; int value; scanf("%s%d", to, &value); add(i, to[0]-'A'+1, value); add(to[0]-'A'+1, i, value); } } printf("%d ", prim(1)); } return 0; }
Kruskal
#include <cstdio> #include <cstring> #include <queue> #include <vector> #include <algorithm> #define INF 0x3F3F3F3F using namespace std; int n, m; int parent[100], rank[100]; struct Edge{int u, v, w;}edge[100]; bool cmp(Edge a, Edge b) { return a.w < b.w; } inline int FindSet(int x) { while(x != parent[x]) x = parent[x]; return x; } void UnionSet(int l, int r) { int x = FindSet(l); int y = FindSet(r); if(rank[x] > rank[y]){ rank[x] += rank[y]; parent[y] = x; } else{ rank[y] += rank[x]; parent[x] = y; } } int kruskal() { for(int i = 1; i <= n; i++){ parent[i] = i; rank[i] = 1; } int ans = 0; sort(edge+1, edge+m+1, cmp); for(int i = 1, num = 0; num < n-1 && i <= m; i++){ int x = FindSet(edge[i].u); int y = FindSet(edge[i].v); if(x != y){ num++; UnionSet(x, y); ans += edge[i].w; } } return ans; } int main() { while(scanf("%d", &n), n){ m = 0; for(int i = 1; i < n; i++){ int k; scanf("%*s%d", &k); while(k--){ m++; edge[m].u = i; char v[2]; scanf("%s%d", v, &edge[m].w); edge[m].v = v[0] - 'A' + 1; //printf("Edge %d : u = %d v = %d w = %d ", m, edge[m].u, edge[m].v, edge[m].w); } } printf("%d ", kruskal()); } return 0; }