码迷,mamicode.com
首页 > 其他好文 > 详细

432423

时间:2018-08-09 13:47:12      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:inf   amp   std   +=   操作   查找   有向环   最小   struct   

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 #define MAXN 1010
  6 #define MAXM 1000000+10
  7 #define INF 0x3f3f3f3f
  8 using namespace std;
  9 struct Edge
 10 {
 11     int from;
 12     int to;
 13     double cost;
 14 } e[MAXM];
 15 struct point
 16 {
 17     double x;
 18     double y;
 19 }p[MAXM];
 20 int pre[MAXN];//存储父节点
 21 int vis[MAXN];//标记作用
 22 int id[MAXN];//id[i]记录节点i所在环的编号
 23 double in[MAXN];//in[i]记录i入边中最小的权值
 24 double dis(point a,point b)
 25 {
 26     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 27 }
 28 double zhuliu(int root, int n, int m)//root根 n点数 m边数
 29 {
 30     double res;
 31     int u, v;
 32     int i;
 33     while(1)
 34     {
 35         for(i = 0; i < n; i++)
 36             in[i] = INF;//初始化
 37         for(i = 0; i < m; i++)
 38         {
 39             Edge E = e[i];
 40             if(E.from != E.to && E.cost < in[E.to])
 41             {
 42                 pre[E.to] = E.from;//记录前驱
 43                 in[E.to] = E.cost;//更新
 44             }
 45         }
 46         for(i = 0; i < n; i++)
 47         {
 48             if(i != root && in[i] == INF)///除了根以外还有点没有入边,则不存在最小树形图
 49             {
 50                 return -1;
 51             }
 52         }
 53         //找有向环
 54         int tn = 0;//记录当前查找中 环的总数
 55         memset(id, -1, sizeof(id));
 56         memset(vis, -1, sizeof(vis));
 57         in[root] = 0;//
 58         for(i = 0; i < n; i++)
 59         {
 60             res += in[i];//累加
 61             v = i;
 62             //找图中的有向环 三种情况会终止while循环
 63             //1,直到出现带有同样标记的点说明成环
 64             //2,节点已经属于其他环
 65             //3,遍历到根
 66             while(vis[v] != i && id[v] == -1 && v != root)
 67             {
 68                 vis[v] = i;//标记
 69                 v = pre[v];//一直向上找
 70             }
 71             //因为找到某节点属于其他环  或者 遍历到根  说明当前没有找到有向环
 72             if(v != root && id[v] == -1)//必须上述查找已经找到有向环
 73             {
 74                 for(int u = pre[v]; u != v; u = pre[u])
 75                 {
 76                     id[u] = tn;//记录节点所属的 环编号
 77                 }
 78                 id[v] = tn++;//记录节点所属的 环编号  环编号累加
 79             }
 80         }
 81         if(tn == 0)
 82         {
 83             break;///不存在有向环
 84         }
 85         for(i = 0; i < n; i++) //可能存在独立点
 86         {
 87             if(id[i] == -1)
 88             {
 89                 id[i] = tn++;//环数累加
 90             }
 91         }
 92         for(i = 0; i < m; i++)///缩点,重新标记
 93         {
 94             v = e[i].to;
 95             e[i].from = id[e[i].from];
 96             e[i].to = id[e[i].to];
 97             //<u, v>有向边
 98             //两点不在同一个环 u到v的距离为 边权cost - in[v]
 99             if(e[i].from != e[i].to)
100             {
101                 e[i].cost -= in[v];//更新边权值 继续下一条边的判定
102             }
103         }
104         n = tn;///以环总数为下次操作的点数 继续执行上述操作 直到没有环
105         root = id[root];
106     }
107     return res;
108 }
109 int main()
110 {
111     int n,m;
112     while(scanf("%d%d",&n,&m)!=EOF)
113     {
114         int i;
115         double ans;
116         for(i=0; i<n; i++)
117         {
118             scanf("%lf%lf",&p[i].x,&p[i].y);
119         }
120         for(i=0; i<m; i++)
121         {
122             scanf("%d%d",&e[i].from,&e[i].to);
123             e[i].from--;
124             e[i].to--;
125             if(e[i].from!=e[i].to)
126             {
127                 e[i].cost=dis(p[e[i].from],p[e[i].to]);
128             }
129             else
130             {
131                 e[i].cost=INF;
132             }
133         }
134         ans=zhuliu(0,n,m);
135         if(ans==-1)
136         {
137             printf("poor snoopy\n");
138         }
139         else
140         {
141             printf("%.2f\n",ans);
142         }
143     }
144     return 0;
145 }

 

432423

标签:inf   amp   std   +=   操作   查找   有向环   最小   struct   

原文地址:https://www.cnblogs.com/wkfvawl/p/9447929.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!