• POJ 3164 Command Network(最小树形图)


    链接:http://poj.org/problem?id=3164

    本文链接:http://www.cnblogs.com/Ash-ly/p/5532260.html

    题意:

      有一个指挥网络被战争破坏了,你的任务是建立一个临时的通信网络.这个网络最重要的的一点是能够把命令传到被摧毁的网络的每个点上,所以要建立一个单向的传输网络.假设所有的传输节点都分别分布在一个平面上.如果命令要想从节点A传送到结点B上,必须建立一条单向电缆从节点A连接到结点B.因为是战争时期,不能任意两个节点之间都要连接,所以让你给出满足要求的通信网络所需要的最少的电缆的长度.

    思路:

      电缆的传输信息是单向的,并且命令只要能够传下去就可以,不需要反馈回来.所以可以建立有向图,很显然求得是这个有向图上的最小树形图.这里直接用朱刘算法求最小树形图了.这道题WA了好几次,最后看到一句话"用double时,输入要用%lf输出要用%f".......这题有毒~

    代码:

      1 #include <iostream>
      2 #include <cmath>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <algorithm>
      7 #include <string>
      8 #include <queue>
      9 #include <stack>
     10 #include <vector>
     11 #include <map>
     12 typedef long long LL;
     13 using namespace std;
     14 const int MAXV = 100;
     15 const int MAXE = 10000;
     16 const int INF = 0x3f3f3f3f;
     17 
     18 struct Point{
     19     int x;
     20     int y;
     21 }pt[MAXV + 7];
     22 
     23 double zhuliu(int root, int V, double map[MAXV + 7][MAXV + 7]){
     24     bool visited[MAXV + 7];
     25     bool flag[MAXV + 7];
     26     int pre[MAXV + 7];
     27     double sum = 0;
     28     int i, j, k;
     29     for(i = 0; i <= V; i++) flag[i] = false, map[i][i] = INF;
     30     pre[root] = root;
     31     while(true){
     32         for(i = 1; i <= V; i++){
     33             if(flag[i] || i == root) continue;
     34             pre[i] = i;
     35             for(j = 1; j <= V; j++)
     36                 if(!flag[j] && map[j][i] < map[pre[i]][i])
     37                     pre[i] = j;
     38             if(pre[i] == i) return -1;
     39         }
     40         for(i = 1; i <= V; i++){
     41             if(flag[i] || i == root) continue;
     42             for(j = 1; j <= V; j++) visited[j] = false;
     43             visited[root] = true;
     44             j = i;
     45             do{
     46                 visited[j] = true;
     47                 j = pre[j];
     48             }while(!visited[j]);
     49             if(j != i)continue;
     50             i = j;
     51             do{
     52                 sum += map[pre[j]][j];
     53                 j = pre[j];
     54             }while(j != i);
     55             j = i;
     56             do{
     57                 for(k = 1; k <= V; k++)
     58                     if(!flag[k] && map[k][j] < INF && k != pre[j])
     59                         map[k][j] -= map[pre[j]][j];
     60                 j = pre[j];
     61             }while(j != i);
     62             for(j = 1; j <= V; j++){
     63                 if(j == i) continue;
     64                 for(k = pre[i]; k != i; k = pre[k]){
     65                     if(map[k][j] < map[i][j]) map[i][j] = map[k][j];
     66                     if(map[j][k] < map[j][i]) map[j][i] = map[j][k];
     67                 }
     68             }
     69             for(j = pre[i]; j != i; j = pre[j]) flag[j] = true;
     70             break;
     71         }
     72         if(i > V){
     73             for(i = 1; i <= V; i++)
     74                 if(!flag[i] && i != root) sum += map[pre[i]][i];
     75             break;
     76         }
     77     }
     78     return sum;
     79 }
     80 
     81 double dist(struct Point a, struct Point b)
     82 {
     83     return hypot(a.x - b.x, a.y - b.y);
     84 }
     85 
     86 int main()
     87 {
     88     //freopen("input.txt", "r", stdin);
     89     int n, m;
     90     while(~scanf("%d%d", &n, &m)){
     91         double map[MAXV + 7][MAXV + 7] = {0};
     92         for(int i = 0; i <= n; i++) for(int j = 0; j <= n; j++) map[i][j] = INF;
     93         memset(&pt, 0, sizeof(Point));
     94         for(int i = 1; i <= n; i++) scanf("%d%d", &pt[i].x, &pt[i].y);
     95         for(int i = 0; i < m; i++){
     96             int u, v;
     97             scanf("%d%d", &u, &v);
     98             map[u][v] = dist(pt[u], pt[v]);
     99         }
    100         double ans = zhuliu(1, n, map);
    101         if(ans != -1)    printf("%.2f
    ", ans);
    102         else printf("poor snoopy
    ");
    103     }
    104     return 0;
    105 }

     

  • 相关阅读:
    LevelDB
    Erlang的gen_server的terminate()/2未执行
    集群间心跳检测
    AI从业者关于数学的一些小建议
    《百面机器学习》拾贝----第三章:经典算法
    Demo——Image classification
    《百面机器学习》拾贝----第二章:模型评估
    《百面机器学习》拾贝----第一章:特征工程
    算法工程师---职业生涯规划
    License Plate Detection and Recognition in Unconstrained Scenarios(无约束场景下的车牌检测与识别)
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5532260.html
Copyright © 2020-2023  润新知