zoukankan      html  css  js  c++  java
  • 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 }

     

  • 相关阅读:
    char/byte/short类型的加法和类型转换问题
    Java四种基本数据类型
    Git知识集锦
    解决给自己的博客添加百度统计不能验证的问题
    C++静态代码分析工具推荐——PVS-Studio
    Qt在控件未显示时如何获取正确的控件尺寸
    C#程序如何捕捉未try/catch的异常——不弹“XXX已停止工作”报错框
    win10下vs2015编译的程序如何运行在win7等系统(无需安装Redistributable)
    Qt分页导航控件
    win server 2008配置ftp无法登陆问题的解决办法
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5532260.html
Copyright © 2011-2022 走看看