Prim小练习1
题目大意:
给出n个truck type, 这些truck type之间的距离为他们的字符串之中不同的字母个数
要求使得1/sigma(d(t0, td))最大,即使得距离和最小,那么僵所有的不同的truck type视为不同的点,距离作为权值求最小生成树的权值和即可
自从学MST以来一直在用Kruskal算法,很少用Prim,现在做一些MST的题目,l练习一下Prim算法
代码如下:
Kruskal算法的方法:
Result : Accepted Memory : 30488 KB Time : 891 ms
/* * Author: Gatevin * Created Time: 2014/7/16 19:21:10 * File Name: test.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; int V,E; string s[2010]; int u[2100000]; int v[2100000]; int w[2100000]; int r[2100000]; int f[2010]; int get_father(int i) { if(i != f[i]) { f[i] = get_father(f[i]); } return f[i]; } bool cmp(const int& i, const int& j) { return w[i] < w[j]; } int Kruskal() { int ret = 0; sort(r + 1, r + E + 1, cmp); for(int i = 1; i <= E; i++) { int e = r[i]; int rx = get_father(u[e]); int ry = get_father(v[e]); if(rx != ry) { ret += w[e]; f[rx] = ry; } } return ret; } int main() { while(scanf("%d",&V) == 1 && V) { for(int i = 1; i <= V; i++) { cin>>s[i]; f[i] = i; } E = 0; int distance; for(int i = 1; i <= V; i++) { for(int j = i + 1; j <= V; j++) { distance = 0; for(int k = 0; k < 7; k++) { if(s[i][k] != s[j][k]) distance++; } E++; r[E] = E; u[E] = i; v[E] = j; w[E] = distance; } } int answer = Kruskal(); printf("The highest possible quality is 1/%d.\n",answer); } return 0; }
Result : Accepted Memory : 38100 KB Time : 1532 ms
/* * Author: Gatevin * Created Time: 2014/7/16 19:31:41 * File Name: test.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; const int inf = 0x3f3f3f3f; int dis[2010]; int vis[2010]; string s[2010]; vector <pair<int, int> > g[2010]; int V; int Prim() { memset(vis, 0, sizeof(vis)); fill(dis + 1, dis + V + 1, inf); dis[1] = 0; int ans = 0; for(int i = 1; i <= V; i++) { int mark = -1; for(int j = 1; j <= V; j++) { if(!vis[j]) { if(mark == -1) { mark = j; } else { if(dis[j] <= dis[mark]) mark = j; } } } if(mark == -1) break; vis[mark] = 1; ans += dis[mark]; for(int j = 0; j < g[mark].size(); j++) { if(!vis[g[mark][j].first]) { int x = g[mark][j].first; dis[x] = min(dis[x], g[mark][j].second); } } } for(int i = 1; i <= V; i++) { if(!g[i].empty()) { g[i].clear(); } } return ans; } int main() { while(scanf("%d",&V) && V) { for(int i = 1; i <= V; i++) { cin>>s[i]; } int dif; for(int i = 1; i <= V; i++) { for(int j = i + 1; j <= V; j++) { dif = 0; for(int k = 0; k < 7; k++) { if(s[i][k] != s[j][k]) dif++; } g[i].push_back(make_pair(j, dif));//邻接表 g[j].push_back(make_pair(i, dif)); } } int answer = Prim(); printf("The highest possible quality is 1/%d.\n",answer); } return 0; }