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

题目链接:

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

题目大意:

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

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

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<queue>
  7 #include<stack>
  8 #include<map>
  9 #include<set>
 10 #include<sstream>
 11 using namespace std;
 12 typedef long long ll;
 13 const int maxn = 1e3 + 10;
 14 const int INF = 1 << 30;
 15 int dir[4][2] = {1,0,0,1,-1,0,0,-1};
 16 int T, n, m;
 17 struct edge
 18 {
 19     int u, v, w;
 20     edge(){}
 21     edge(int u, int v, int w):u(u), v(v), w(w){}
 22     bool operator <(const edge& a)const
 23     {
 24         return w < a.w;
 25     }
 26 };
 27 edge a[maxn];
 28 int par[60], high[60];
 29 //初始化n个元素
 30 void init(int n)
 31 {
 32     for(int i = 0; i < n; i++)
 33     {
 34         par[i] = i;
 35         high[i] = 0;
 36     }
 37 }
 38 //查询树的根
 39 int Find(int x)
 40 {
 41     return par[x] == x ? x : par[x] = Find(par[x]);//路径压缩
 42 }
 43 void unite(int x, int y)
 44 {
 45     x = Find(x);
 46     y = Find(y);
 47     if(x == y)return;
 48     if(high[x] < high[y])par[x] = y;//y的高度高,将x的父节点设置成y
 49     else
 50     {
 51         par[y] = x;
 52         if(high[x] == high[y])high[x]++;
 53     }
 54 }
 55 bool same(int x, int y)
 56 {
 57     return Find(x) == Find(y);
 58 }
 59 void kruskal(int n, int m)//点数n,边数m
 60 {
 61     int sum_mst = 0;//mst权值
 62     int num= 0;//已经选择的边的边数
 63     sort(a, a + m);//边进行排序
 64     init(n);//初始化并查集
 65     for(int i = 0; i < m; i++)
 66     {
 67         int u = a[i].u;
 68         int v = a[i].v;
 69         if(Find(u - 1) != Find(v - 1))//图最开始的下标是1,并查集是0
 70         {
 71             //printf("%d %d %d\n", u, v, a[i].w);
 72             sum_mst += a[i].w;
 73             num++;
 74             unite(u - 1, v - 1);
 75         }
 76         if(num >= n - 1)break;
 77     }
 78     //printf("weight of mst is %d\n", sum_mst);
 79     cout<<sum_mst<<endl;
 80 }
 81 map<char, int>id;
 82 set<char>s;
 83 int getid(char c)
 84 {
 85     if(s.count(c))return id[c];
 86     else
 87     {
 88         s.insert(c);
 89         return id[c] = s.size();
 90     }
 91 }
 92 int main()
 93 {
 94     while(cin >> n && n)
 95     {
 96         char c, d;
 97         id.clear();
 98         s.clear();
 99         int tot = 0;
100         for(int i = 1; i < n; i++)
101         {
102             cin >> c >> m;
103             int u = getid(c), v, w;
104             while(m--)
105             {
106                 cin >> d >> w;
107                 v = getid(d);
108                 a[tot++] = edge(u, v, w);
109             }
110         }
111         kruskal(n, tot);
112     }
113     return 0;
114 }

 

posted @ 2018-04-06 13:17  _努力努力再努力x  阅读(146)  评论(0编辑  收藏  举报