Gym - 100203H Highways 最小生成树
题意:平面上n个点修路,已经修好了m条,再修若干条使得点之间连通,求最小代价的方案。
思路:基本上是裸的最小生成树了,我这里存边直接存在multyset了,取的时候也比较方便,我本来就是这么考虑的,队友打了一发朴素的排序的超时了。
1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <algorithm> 5 #include <cmath> 6 #include <deque> 7 #include <vector> 8 #include <queue> 9 #include <string> 10 #include <cstring> 11 #include <map> 12 #include <stack> 13 #include <set> 14 #define LL long long 15 #define eps 1e-8 16 #define INF 0x3f3f3f3f 17 #define MAXN 755 18 using namespace std; 19 struct Edge{ 20 int from, to; 21 LL dis; 22 Edge(int from, int to, LL dis):from(from), to(to), dis(dis){}; 23 bool operator <(const Edge &b) const{ 24 return dis < b.dis; 25 } 26 }; 27 multiset<Edge> s; 28 struct Point{ 29 int x, y; 30 }p[MAXN]; 31 LL dis[MAXN][MAXN]; 32 bool vis[MAXN][MAXN]; 33 int father[MAXN]; 34 int scan(){ 35 int res = 0, ch, flag = 0; 36 37 if((ch = getchar()) == '-') 38 flag = 1; 39 40 else if(ch >= '0' && ch <= '9') 41 res = ch - '0'; 42 while((ch = getchar()) >= '0' && ch <= '9' ) 43 res = res * 10 + ch - '0'; 44 45 return flag ? -res : res; 46 } 47 LL getdis(Point a, Point b){ 48 LL x = abs(a.x - b.x); 49 LL y = abs(a.y - b.y); 50 return x * x + y * y; 51 } 52 int find(int x){ 53 if(father[x] == x) return x; 54 father[x] = find(father[x]); 55 return father[x]; 56 } 57 int main() 58 { 59 #ifndef ONLINE_JUDGE 60 freopen("in.txt", "r", stdin); 61 //freopen("out.txt", "w", stdout); 62 #endif // OPEN_FILE 63 int n = scan(); 64 for(int i = 1; i <= n; i++){ 65 father[i] = i; 66 p[i].x = scan(); 67 p[i].y = scan(); 68 } 69 s.clear(); 70 LL dis; 71 for(int i = 1; i <= n; i++){ 72 for(int j = i + 1; j <= n; j++){ 73 dis = getdis(p[i] ,p[j]); 74 s.insert(Edge(i, j, dis)); 75 } 76 } 77 int m =scan(); 78 int x, y; 79 for(int i = 1; i <= m; i++){ 80 x = scan(); 81 y = scan(); 82 vis[x][y] = true; 83 x = find(x); 84 y = find(y); 85 if(x == y) continue; 86 father[x] = y; 87 } 88 multiset<Edge>::iterator it = s.begin(); 89 while(it != s.end()){ 90 Edge u = *it; 91 it++; 92 if(vis[u.from][u.to] || vis[u.to][u.from]) continue; 93 x = find(u.from); 94 y = find(u.to); 95 if(x == y) continue; 96 father[x] = y; 97 printf("%d %d\n", u.from, u.to); 98 } 99 100 }