POJ-1751 Highways---确定部分边的MST

题目链接:

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

题目大意:

有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输出需要添加边的两端点编号即可.

思路:

这里已经有部分边,要求剩下的MST,一开始没想到技巧,后来发现只要将已有的边的权值设置为0就可以直接求MST,这是一个很重要的技巧,如果已经确定的部分边,那就直接把这些边的权值设置成0,求出MST之后一定是包含这些边的MST。

 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 typedef pair<int, int> Pair;
14 const int maxn = 1e3 + 10;
15 const int INF = 1 << 30;
16 int dir[4][2] = {1,0,0,1,-1,0,0,-1};
17 int T, n, m;
18 double Map[maxn][maxn];//存图
19 double lowcost[maxn];
20 int mst[maxn];
21 Pair a[maxn];
22 void prim(int u)//最小生成树起点
23 {
24     for(int i = 1; i <= n; i++)//初始化两个数组
25     {
26         lowcost[i] = Map[u][i];
27         mst[i] = u;
28     }
29     mst[u] = -1;//设置成-1表示已经加入mst
30     for(int i = 1; i <= n; i++)
31     {
32         double minn = INF;
33         int v = -1;
34         //在lowcost数组中寻找未加入mst的最小值
35         for(int j = 1; j <= n; j++)
36         {
37             if(mst[j] != -1 && lowcost[j] < minn)
38             {
39                 v = j;
40                 minn = lowcost[j];
41             }
42         }
43         if(v != -1)//v=-1表示未找到最小的边,
44         {//v表示当前距离mst最短的点
45             //printf("%d %d %d\n", mst[v], v, lowcost[v]);//输出路径
46             if(Map[mst[v]][v])printf("%d %d\n", mst[v], v);
47             mst[v] = -1;
48             for(int j = 1; j <= n; j++)//更新最短边
49             {
50                 if(mst[j] != -1 && lowcost[j] > Map[v][j])
51                 {
52                     lowcost[j] = Map[v][j];
53                     mst[j] = v;
54                 }
55             }
56         }
57     }
58     //printf("weight of mst is %d\n", sum_mst);
59 }
60 int main()
61 {
62     cin >> n;
63     for(int i = 1; i <= n; i++)cin >> a[i].first >> a[i].second;
64     for(int i = 1; i <= n; i++)
65     {
66         for(int j = i; j <= n; j++)
67         {
68             Map[i][j] = Map[j][i] = sqrt((a[i].first - a[j].first) * (a[i].first - a[j].first) + (a[i].second - a[j].second) * (a[i].second - a[j].second));
69         }
70     }
71     cin >> m;
72     int x, y;
73     for(int i = 0; i < m; i++)//将已有的边的权值设置为0!!!
74     {
75         cin >> x >> y;
76         Map[x][y] = Map[y][x] = 0;
77     }
78     prim(1);
79     return 0;
80 }

 

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