给出平面上一些点,和连接它们的带权有向边,求把所有点连起来的最小总权值。

分析

由于这里边是有向的(unidirectional),所以这是经典的最小树形图问题,可以说是最小树形图的模板题。

代码

这个写法是我乱想的。最近写图啊树啊都喜欢开一个结构体~

这个代码在poj上交,如果用g++的话会WA,因为奇怪的poj需要用%f输出浮点数。更奇怪的是c++直接编译错误,不想说了。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cmath>
  4. #include<algorithm>
  5. using namespace std;
  6. const int maxn=202;
  7. const double inf=1e100;
  8. bool bian[maxn][maxn];
  9. struct node {
  10. double x,y;
  11. } a[maxn];
  12. double dist(node &a,node &b) {
  13. return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
  14. }
  15. struct edge {
  16. int v;
  17. double w;
  18. int nxt;
  19. };
  20. struct graph {
  21. edge e[maxn*maxn];
  22. int h[maxn],tot,n,from[maxn],tic[maxn],tim,root,sta[maxn],top;
  23. double in[maxn],mi[maxn];
  24. bool vis[maxn],able[maxn];
  25. void clear() {
  26. memset(h,0,sizeof h);
  27. tot=0;
  28. }
  29. void add(int u,int v,double w) {
  30. e[++tot]=(edge){v,w,h[u]};
  31. h[u]=tot;
  32. }
  33. void dfs(int x) {
  34. vis[x]=true;
  35. for (int i=h[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v) if (able[v]) {
  36. if (v!=root && in[v]>e[i].w) in[v]=e[i].w,from[v]=x;
  37. if (!vis[v]) dfs(v);
  38. }
  39. }
  40. bool circle() {
  41. memset(tic,0,sizeof tic),tim=0;
  42. for (int i=1;i<=n;++i) if (able[i]) {
  43. ++tim;
  44. top=0;
  45. for (int j=i;j;j=from[j]) if (!tic[j]) tic[j]=tim,sta[++top]=j; else if (tic[j]==tim) {
  46. for (int k=1;k<=n;++k) if (tic[k]==tim) tic[k]=0;
  47. do {
  48. tic[sta[top--]]=tim;
  49. } while (sta[top+1]!=j);
  50. return true;
  51. }
  52. }
  53. return false;
  54. }
  55. bool work(double &ret) {
  56. memset(vis,0,sizeof vis);
  57. fill(in+1,in+n+1,inf);
  58. dfs(root);
  59. for (int i=1;i<=n;++i) if (able[i] && !vis[i]) {
  60. ret=-1;
  61. return false;
  62. }
  63. bool cc=circle();
  64. if (cc) {
  65. for (int i=1;i<=n;++i) if (able[i] && i!=root && tic[i]==tim) ret+=in[i];
  66. } else {
  67. for (int i=1;i<=n;++i) if (able[i] && i!=root) ret+=in[i];
  68. }
  69. return cc;
  70. }
  71. void reduce() {
  72. fill(mi+1,mi+n+1,inf);
  73. for (int i=1;i<=n;++i) if (able[i] && tic[i]!=tim) {
  74. double w=inf;
  75. for (int j=h[i],v=e[j].v;j;j=e[j].nxt,v=e[j].v) if (tic[v]==tim) w=min(w,e[j].w-in[v]);
  76. if (w!=inf) add(i,n+1,w);
  77. }
  78. for (int i=1;i<=n;++i) if (able[i] && tic[i]==tim) for (int j=h[i],v=e[j].v;j;j=e[j].nxt,v=e[j].v) if (able[v] && tic[v]!=tim) mi[v]=min(mi[v],e[j].w);
  79. for (int i=1;i<=n;++i) if (able[i] && tic[i]!=tim && mi[i]!=inf) add(n+1,i,mi[i]);
  80. for (int i=1;i<=n;++i) if (tic[i]==tim) able[i]=false;
  81. ++n;
  82. if (!able[root]) root=n;
  83. }
  84. double MGT(int _n) {
  85. memset(able,true,sizeof able),n=_n,root=1;
  86. double ret=0;
  87. while (work(ret)) {
  88. reduce();
  89. }
  90. return ret;
  91. }
  92. } A;
  93. int main() {
  94. #ifndef ONLINE_JUDGE
  95. freopen("test.in","r",stdin);
  96. freopen("my.out","w",stdout);
  97. #endif
  98. int n,m;
  99. while (~scanf("%d%d",&n,&m)) {
  100. A.clear();
  101. memset(bian,0,sizeof bian);
  102. for (int i=1;i<=n;++i) scanf("%lf%lf",&a[i].x,&a[i].y);
  103. for (int i=1;i<=m;++i) {
  104. int u,v;
  105. scanf("%d%d",&u,&v);
  106. if (u==v || bian[u][v]) continue;
  107. bian[u][v]=true;
  108. double d=dist(a[u],a[v]);
  109. A.add(u,v,d);
  110. }
  111. double ans=A.MGT(n);
  112. if (ans<0) puts("poor snoopy"); else printf("%.2lf\n",ans);
  113. }
  114. return 0;
  115. }

poj3164-Command Network的更多相关文章

  1. POJ3164 Command Network —— 最小树形图

    题目链接:https://vjudge.net/problem/POJ-3164 Command Network Time Limit: 1000MS   Memory Limit: 131072K ...

  2. POJ3164 Command Network(最小树形图)

    图论填个小坑.以前就一直在想,无向图有最小生成树,那么有向图是不是也有最小生成树呢,想不到还真的有,叫做最小树形图,网上的介绍有很多,感觉下面这个博客介绍的靠谱点: http://www.cnblog ...

  3. POJ3164:Command Network(有向图的最小生成树)

    Command Network Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 20766   Accepted: 5920 ...

  4. Command Network

    Command Network Time Limit: 1000MSMemory Limit: 131072K Total Submissions: 11970Accepted: 3482 Descr ...

  5. POJ 3164 Command Network 最小树形图

    题目链接: 题目 Command Network Time Limit: 1000MS Memory Limit: 131072K 问题描述 After a long lasting war on w ...

  6. POJ3436 Command Network [最小树形图]

    POJ3436 Command Network 最小树形图裸题 傻逼poj回我青春 wa wa wa 的原因竟然是需要%.2f而不是.2lf 我还有英语作业音乐作业写不完了啊啊啊啊啊啊啊啊啊 #inc ...

  7. POJ 3164 Command Network ( 最小树形图 朱刘算法)

    题目链接 Description After a long lasting war on words, a war on arms finally breaks out between littlek ...

  8. Command Network OpenJ_Bailian - 3436(最小有向生成树模板题)

    链接: http://poj.org/problem?id=3164 题目: Command Network Time Limit: 1000MS   Memory Limit: 131072K To ...

  9. poj 3164 Command Network(最小树形图模板)

    Command Network http://poj.org/problem?id=3164 Time Limit: 1000MS   Memory Limit: 131072K Total Subm ...

  10. POJ 3164——Command Network——————【最小树形图、固定根】

    Command Network Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 15080   Accepted: 4331 ...

随机推荐

  1. vuetify.js框架 下拉框数据改变DOM原数据未清除

    今天遇到一个奇怪的bug 需求很简单,就是将“引擎能力”下拉框选中的值作为筛选条件传入到“样本类型”下拉框中,默认“样本类型”下拉框显示所有样本类型 看图: 如图所示,功能很简单. 其实还是对vuet ...

  2. WPF的退出

    很多时候,会自己写退出程序的代码. 比如,先显示登录框(LogIn),成功后隐藏它,并显示一个主窗体(MainWin),或者外部还调用了其他App,当你关闭MainWin不一定会直接退出整个程序的. ...

  3. 在Linux CentOS7系统中搭建LNMP

    LNMP就是Linux+Nginx+MySQL+PHP,既然是在Linux CentOS7那么Linux就是已经安装好了.所以接下百度一下接下来的教程,整理测试如下: 教程是centos6.2的有点老 ...

  4. Pycharm中查看方法的源码

    方法1.鼠标放在函数上,Ctrl+B,看源码 方法2.将光标移动至要查看的方法处,按住ctrl 键,点击鼠标左键,即可查看该方法的源码.

  5. 第5章 Linux网络编程基础

    第5章 Linux网络编程基础 5.1 socket地址与API 一.理解字节序 主机字节序一般为小端字节序.网络字节序一般为大端字节序.当格式化的数据在两台使用了不同字节序的主机之间直接传递时,接收 ...

  6. leetcode-全排列详解(回溯算法)

     全排列     给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2 ...

  7. Python3 数值类型与运算符

    1.数值类型与进制 (1)基本类型 整型:int 浮点型:float 布尔类型:bool 复数:complex print(type(1)) print(type(1.1)) print(type(F ...

  8. 怎么用js精确判断li已经在ul存在过了?

    <ul class="memory_messagelist" id="memory_messagelist"> <li><span ...

  9. BZOJ 4176 Lucas的数论 莫比乌斯反演+杜教筛

    题意概述:求,n<=10^9,其中d(n)表示n的约数个数. 分析: 首先想要快速计算上面的柿子就要先把d(ij)表示出来,有个神奇的结论: 证明:当且仅当a,b没有相同的质因数的时候我们统计其 ...

  10. 左值&右值

    一.引子 我们所谓的左值.右值,正确的说法应该是左值表达式.右值表达式. 因为C++的表达式不是左值就是右值. 在C中,左值指的是既能够出现在等号左边也能出现在等号右边的表达式,右值指的则是只能出现在 ...