zoukankan      html  css  js  c++  java
  • uva 1494(MST+LCA)

    题意:有n个点告诉你每个点坐标和他上面的权值,任意两个点之间都有边权值是他们的距离,现在能免去花费一条边,定义a为这条边两个结点权值之和,b连通其余节点的最小花费,现在求a/b的最大值。

    思路:先求最小生成树,然后枚举每条变,若加上边会成环则删除环上除去这条边的权值最大的边。

    代码如下:

      1 /**************************************************
      2  * Author     : xiaohao Z
      3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
      4  * Last modified : 2014-02-08 13:40
      5  * Filename     : uva_1494.cpp
      6  * Description     : 
      7  * ************************************************/
      8 
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <cmath>
     14 #include <algorithm>
     15 #include <queue>
     16 #include <stack>
     17 #include <vector>
     18 #include <set>
     19 #include <map>
     20 #define MP(a, b) make_pair(a, b)
     21 #define PB(a) push_back(a)
     22 
     23 using namespace std;
     24 typedef long long ll;
     25 typedef pair<int, int> pii;
     26 typedef pair<unsigned int,unsigned int> puu;
     27 typedef pair<int, double> pid;
     28 typedef pair<ll, int> pli;
     29 typedef pair<int, ll> pil;
     30 
     31 const int INF = 0x3f3f3f3f;
     32 const double eps = 1E-6;
     33 const int LEN = 1010;
     34 const int LOGLEN = 22;
     35 vector<pid> Map[LEN];
     36 int n, m, top, fa[LEN], dep[LEN], parent[LOGLEN][LEN], tag[LEN*LEN];
     37 double rd[LOGLEN][LEN];
     38 struct V{double x, y, val;};
     39 struct E{
     40      int u, v;
     41      double val;
     42 };
     43 E edge[LEN*LEN];
     44 V vv[LEN];
     45 
     46 double dis(int a, int b){
     47     return sqrt((vv[a].x-vv[b].x)*(vv[a].x-vv[b].x) + (vv[a].y-vv[b].y)*(vv[a].y-vv[b].y));
     48 }
     49 bool cmp(E a, E b){ return a.val < b.val;}
     50 //UFSet
     51 void init(){for(int i=0; i<LEN; i++) {fa[i] = i;Map[i].clear();}}
     52 int Find(int x){return fa[x] == x? x: fa[x] = Find(fa[x]);}
     53 //MST
     54 double kruskal(){
     55     int cnt = 0;
     56     double    ret = 0;
     57     sort(edge, edge+top, cmp);
     58     for(int i=0; i<top; i++){
     59         int pa = Find(edge[i].u), pb = Find(edge[i].v);
     60         if(pa == pb) continue;
     61         fa[pa] = pb;
     62         tag[i] = 1;
     63         Map[edge[i].u].PB(MP(edge[i].v, edge[i].val));
     64         Map[edge[i].v].PB(MP(edge[i].u, edge[i].val));
     65         cnt++; ret+=edge[i].val;
     66         if(cnt == n-1) break;
     67     }
     68     return ret;
     69 }
     70 //LCA
     71 void dfs(int v, int fa, int d){
     72     parent[0][v] = fa;
     73     rd[0][v] = -1;
     74     dep[v] = d;
     75     for(int i=0; i<Map[v].size(); i++){
     76         int x = Map[v][i].first;
     77            double y = Map[v][i].second;
     78         if(x != fa)dfs(x, v, d+1);
     79         else rd[0][v] = y;
     80     }
     81 }
     82 
     83 void initLCA(int root){
     84     memset(rd, 0, sizeof rd);
     85     dfs(root, -1, 0);
     86     for(int i=0; i<LOGLEN-1; i++)
     87         for(int j=0; j<n; j++){
     88             if(parent[i][j]<0) rd[i+1][j] = parent[i+1][j] = -1;
     89             else{
     90                 parent[i+1][j] = parent[i][parent[i][j]];
     91                 rd[i+1][j] = max(rd[i][parent[i][j]], rd[i][j]);     
     92             }        
     93         }
     94 }
     95 
     96 double LCA(int u, int v){
     97     if(dep[u] > dep[v]) swap(u, v);
     98     double ret = 0;
     99     for(int i=0; i<LOGLEN; i++)
    100         if(((dep[v] - dep[u]) >> i) & 1){
    101             ret = max(ret, rd[i][v]);
    102             v = parent[i][v];
    103         }
    104     if(u == v) return ret;
    105     for(int i=LOGLEN-1; i>=0; i--)
    106         if(parent[i][u] != parent[i][v]){
    107             ret = max(ret, rd[i][u]);
    108             ret = max(ret, rd[i][v]);
    109             u = parent[i][u];
    110             v = parent[i][v];
    111         }
    112     ret = max(ret, rd[0][u]);
    113     ret = max(ret, rd[0][v]);
    114     return ret;
    115 }
    116 
    117 int main()
    118 {
    119 //    freopen("in.txt", "r", stdin);
    120 
    121     int T;
    122     scanf("%d", &T);
    123     while(T--){
    124         scanf("%d", &n);
    125         for(int i=0; i<n; i++)
    126            scanf("%lf%lf%lf", &vv[i].x, &vv[i].y, &vv[i].val);
    127         top = 0;memset(tag, 0, sizeof tag);
    128         for(int i=0; i<n; i++)
    129             for(int j=i+1; j<n; j++){
    130                 edge[top].u = i;
    131                 edge[top].v = j;
    132                 edge[top++].val = dis(i, j);
    133             }
    134         init();
    135         double aval = kruskal(), ans = 0;
    136         initLCA(0);
    137         for(int i=0; i<top; i++){
    138             int a = edge[i].u, b = edge[i].v;
    139             double tl = LCA(a, b), A = vv[a].val+vv[b].val, B;
    140             if(tag[i]) B = aval-edge[i].val;
    141             else B = aval - tl;
    142             ans = max(ans, A/B);
    143         }
    144         printf("%.2lf
    ", ans);
    145     }
    146     return 0;
    147 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    鼠标放在图片上出现提示
    NSIS调用dll
    IIS7 CMD命令
    NSIS检测
    NSIS修改文件夹访问权限
    NSIS——检测IIS是否安装及版本
    NSIS——检测SQL Server安装版本
    NSIS使用技巧集合
    提供修复界面的NSIS安装包
    NSIS MUI教程
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3540816.html
Copyright © 2011-2022 走看看