[ An Ac a Day ^_^ ] [kuangbin带你飞]专题六 最小生成树 POJ 1251 Jungle Roads

时间:2023-03-09 04:25:54
[ An Ac a Day ^_^ ] [kuangbin带你飞]专题六 最小生成树 POJ 1251	Jungle Roads

题意:

有n个点 每个点上有一些道路 求最小生成树

解释下输入格式

A n v1 w1 v2 w2

A点上有n条边 A到v1权值是w1 A到v2权值是w2

思路:

字符串处理之后跑kruskal求最小生成树

 /* ***********************************************
Author :Sun Yuefeng
Created Time :2016/11/9 18:26:37
File Name :tree.cpp
************************************************ */ #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<bitset>
#include<map>
#include<set>
#include<stack>
#include<vector>
#include<queue>
#include<list>
#define M(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=;
const int maxm=;
const int mod=1e7+;
int dx[]= {,,,-,,-,,-};
int dy[]= {,-,,,-,,,-}; int f[maxn],tol,n; struct _edge
{
int u,v,w;
friend bool operator < (const _edge a,const _edge b)
{
return a.w<b.w;
}
}edge[maxm]; void addedge(int u,int v,int w) //加边
{
edge[tol].u=u;
edge[tol].v=v;
edge[tol].w=w;
tol++;
} int _find(int x) //并查集
{
if(f[x]==-) return x;
else return f[x]=_find(f[x]);
} int kruskal()
{
M(f,-);
sort(edge,edge+tol); //把所有的边排序
int cnt=,ans=;
int u,v,w,f1,f2;
for(int i=;i<tol;i++) //从权值最小的边开始加
{
u=edge[i].u;
v=edge[i].v;
w=edge[i].w;
f1=_find(u);
f2=_find(v);
if(f1!=f2) //判断是否成环
{
ans+=w;
f[f1]=f2;
cnt++;
}
if(cnt==n-) break;
}
//if(cnt<n-1) return -1; 判断图是否连通
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&n)!=EOF&&n)
{
tol=;
for(int i=;i<n-;i++)
{
char str[];
int num,u,v,w;
scanf("%s",str);
u=str[]-'A';
scanf("%d",&num);
while(num--)
{
scanf("%s",str);
v=str[]-'A';
scanf("%d",&w);
addedge(u,v,w);
}
}
printf("%d\n",kruskal());
}
return ;
}
/* 9
A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
3
A 2 B 10 C 40
B 1 C 20
0 */