题目链接
http://www.lightoj.com/volume_showproblem.php?problem=1041
题目大意
有m个关系, 每个关系是两个城市相距的距离,求把这些城市全部连接起来的最小距离。
解题思路
典型的最小生成树
代码如下
kruskal算法
#include<bits/stdc++.h>
using namespace std;
const int N = 57;
const int INF = 0x3f3f3f3f;
struct edge
{
int u, v, cost;
edge() = default;
edge(int x, int y, int z)
{
u = x, v = y, cost = z;
}
};
edge arr[N];
map<string, int>mp;
set<string> st;
int par[N];
int Rank[N];
void init(int n)
{
for(int i=1; i<=n; ++ i)
par[i] = i, Rank[i] = 0;
}
int Find(int x)
{
if(x == par[x])
return x;
return par[x] = Find(par[x]);
}
void unite(int x, int y)
{
x = Find(x);
y = Find(y);
if(x == y)
return ;
if(Rank[x] < Rank[y])
par[x] = y;
else
{
par[y] = x;
if(Rank[x] == Rank[y])
Rank[x] ++;
}
}
bool same(int x, int y)
{
if(Find(x) == Find(y))
return true;
return false;
}
bool cmp(const edge &a, const edge &b)
{
return a.cost < b.cost;
}
int kruskal(int e, int v)
{
sort(arr, arr+e, cmp);
init(v);
int res = 0;
for(int i=0; i<e; ++ i)
{
edge s = arr[i];
if(same(s.u, s.v) == false)
{
unite(s.u, s.v);
res += s.cost;
}
}
return res;
}
void solve(int cases)
{
int n;
scanf("%d", &n);
string a, b;
int c;
int s = 1;
mp.clear(), st.clear();
for(int i=0; i<n; ++ i)
{
cin >> a >> b >> c;
if(st.count(a) == 0)
{
st.insert(a);
mp[a] = s ++;
}
if(st.count(b) == 0)
{
st.insert(b);
mp[b] = s ++;
}
arr[i] = edge(mp[a], mp[b], c);
}
int res = kruskal(n, s-1);
int is = 0;
for(int i=1; i<s; ++ i)
if(par[i] == i)
is ++;
if(is > 1)
printf("Case %d: Impossible
", cases);
else
printf("Case %d: %d
", cases, res);
}
int main()
{
int t;
scanf("%d", &t);
for(int i=1; i<=t; ++ i)
solve(i);
return 0;
}