• Gym


    题意:平面上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
    ", u.from, u.to);
     98     }
     99 
    100 }
  • 相关阅读:
    理解javascript中的Array类型
    解决EF 4.0 中数据缓存机制
    vim学习之旅01-文本搜索并高亮显示
    Quartz.Net 学习之路02 初探Quartz.Net
    Quartz.Net 学习之路01 安装Quartz.Net
    EasyUI这个框架用了好久了,总结一下遇到的问题和解决方法
    记录剪切板
    如何将Unicode字符转换成简体字
    ass字幕转换成文本文件
    Change WORDS
  • 原文地址:https://www.cnblogs.com/macinchang/p/4733321.html
Copyright © 2020-2023  润新知