Poj 3164 Command Network

描述
一种文字持久的战争后,对武器的战争终于爆发了littleken之间和KnuthOcean的王国。突然和猛烈攻击KnuthOcean的部队已呈现littleken指挥网络彻底失败。必须马上建立临时网络。littleken订单史努比项目负责。
这种情况对每一个细节,史努比认为,当务之急是使littenken的命令到达每一个断开的节点在破坏网络和决定计划建立一个单向通信网络。节点分布在一个平面上。如果littleken的命令可以直接传送从一个节点到另一个节点B,

电线要沿直线段连接的两个节点建立。因为这是在战时,没有之间的所有节点对CAN线建成。史努比想要计划要求导线的最短的总长度,建设可以很快完成。

输入
输入包含多个测试案例。每个测试案例的第一行包含两个整数n(n≤100),在摧毁网络节点数,和M(M≤104),数量的节点对之间的导线,可建。下一行n包含一对有序的XI和易,

给出节点的笛卡尔坐标。

然后按照mlines每个都包含两个整数i和j之间的1和n(含)意义的线可以结我与节点j为前者对后者的单向的命令传递之间建立。littleken总部都位于节点1。进程到文件结束。
输出
对于每个测试用例,输出一行,其中包含最短的总长度到小数点后两位数的总长度。

题解:

最小树形图模板题,直接跑朱刘算法

朱刘算法:http://blog.csdn.net/wsniyufang/article/details/6747392

这一题没有什么别的

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct Node
 8 {
 9     int u,v;
10     double dis;
11 }edge[20001];
12 int n,m;
13 double X[10001],Y[10001],ans,in[10001];
14 int pre[10001],vis[10001],id[10001];
15 void add(int u,int v,double d,int num)
16 {
17     edge[num].u=u;
18     edge[num].v=v;
19     edge[num].dis=d;
20 }
21 int main()
22 {int i,j,u,v,root;
23 //freopen("canal0.in","r",stdin);
24 //freopen("canal.out","w",stdout);
25     cin>>n>>m;
26      for (i=1;i<=n;i++)
27      {
28          scanf("%lf%lf",&X[i],&Y[i]);
29      }
30      for (i=1;i<=m;i++)
31      {
32          scanf("%d%d",&u,&v);
33          add(u,v,sqrt((X[u]-X[v])*(X[u]-X[v])+(Y[u]-Y[v])*(Y[u]-Y[v])),i);
34      }
35      ans=0;root=1;
36       while (1)
37       {//cout<<root<<endl;
38           memset(in,127,sizeof(in));
39            for (i=1;i<=m;i++)
40            if (edge[i].u!=edge[i].v&&edge[i].dis<in[edge[i].v])
41            {
42                in[edge[i].v]=edge[i].dis;
43                pre[edge[i].v]=edge[i].u;
44          }
45          in[root]=0;
46          int cnt=0;
47          memset(id,-1,sizeof(id));
48         memset(vis,-1,sizeof(vis));
49           for (i=1;i<=n;i++)
50           {
51               ans+=in[i];
52                v=i;
53                while (vis[v]!=i&&id[v]==-1&&v!=root)
54                {
55                    vis[v]=i;
56                    v=pre[v];
57              }
58               if (id[v]==-1&&v!=root)
59               {
60                   id[v]=++cnt;
61                    for (j=pre[v];j!=v;j=pre[j]) id[j]=cnt;
62               }
63           }
64            if (cnt==0) break;
65            for (i=1;i<=n;i++) 
66            if (id[i]==-1) id[i]=++cnt;
67             for (i=1;i<=m;i++)
68             {
69                 int v=edge[i].v;
70                 edge[i].u=id[edge[i].u];
71                 edge[i].v=id[edge[i].v];
72                 if (edge[i].u!=edge[i].v) edge[i].dis=edge[i].dis-in[v];
73             }
74         n=cnt;
75         root=id[root];
76       }
77     printf("%.2lf",ans);
78 }

 

posted @ 2017-07-29 10:13  Z-Y-Y-S  阅读(311)  评论(0编辑  收藏  举报