POJ-1251 Jungle Roads---MST裸题(需要编号)

题目链接:

https://vjudge.net/problem/POJ-1251

题目大意:

首先给你一个图,需要你求出最小生成树,输入N个节点,用大写字母表示了节点,然后节点与节点之间有权值。

思路:
这里需要编号,其他的就是模板

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + ;
const int INF = << ;
int dir[][] = {,,,,-,,,-};
int T, n, m;
struct edge
{
int u, v, w;
edge(){}
edge(int u, int v, int w):u(u), v(v), w(w){}
bool operator <(const edge& a)const
{
return w < a.w;
}
};
edge a[maxn];
int par[], high[];
//初始化n个元素
void init(int n)
{
for(int i = ; i < n; i++)
{
par[i] = i;
high[i] = ;
}
}
//查询树的根
int Find(int x)
{
return par[x] == x ? x : par[x] = Find(par[x]);//路径压缩
}
void unite(int x, int y)
{
x = Find(x);
y = Find(y);
if(x == y)return;
if(high[x] < high[y])par[x] = y;//y的高度高,将x的父节点设置成y
else
{
par[y] = x;
if(high[x] == high[y])high[x]++;
}
}
bool same(int x, int y)
{
return Find(x) == Find(y);
}
void kruskal(int n, int m)//点数n,边数m
{
int sum_mst = ;//mst权值
int num= ;//已经选择的边的边数
sort(a, a + m);//边进行排序
init(n);//初始化并查集
for(int i = ; i < m; i++)
{
int u = a[i].u;
int v = a[i].v;
if(Find(u - ) != Find(v - ))//图最开始的下标是1,并查集是0
{
//printf("%d %d %d\n", u, v, a[i].w);
sum_mst += a[i].w;
num++;
unite(u - , v - );
}
if(num >= n - )break;
}
//printf("weight of mst is %d\n", sum_mst);
cout<<sum_mst<<endl;
}
map<char, int>id;
set<char>s;
int getid(char c)
{
if(s.count(c))return id[c];
else
{
s.insert(c);
return id[c] = s.size();
}
}
int main()
{
while(cin >> n && n)
{
char c, d;
id.clear();
s.clear();
int tot = ;
for(int i = ; i < n; i++)
{
cin >> c >> m;
int u = getid(c), v, w;
while(m--)
{
cin >> d >> w;
v = getid(d);
a[tot++] = edge(u, v, w);
}
}
kruskal(n, tot);
}
return ;
}
上一篇:c++ String去除头尾空格


下一篇:git最佳实践之feature和hotfix分支