连接:http://poj.org/problem?id=3164
Time Limit: 1000MS | Memory Limit: 131072K | |
Total Submissions: 10061 | Accepted: 2930 |
Description
After a long lasting war on words, a war on arms finally breaks out between littleken’s and KnuthOcean’s kingdoms. A sudden and violent assault by KnuthOcean’s force has rendered a total failure of littleken’s command network. A provisional network must be built immediately. littleken orders snoopy to take charge of the project.
With the situation studied to every detail, snoopy believes that the most urgent point is to enable littenken’s commands to reach every disconnected node in the destroyed network and decides on a plan to build a unidirectional communication network. The nodes are distributed on a plane. If littleken’s commands are to be able to be delivered directly from a node A to another node B, a wire will have to be built along the straight line segment connecting the two nodes. Since it’s in wartime, not between all pairs of nodes can wires be built. snoopy wants the plan to require the shortest total length of wires so that the construction can be done very soon.
Input
The input contains several test cases. Each test case starts with a line containing two integer N (N ≤ 100), the number of nodes in the destroyed network, and M (M ≤ 104), the number of pairs of nodes between which a wire can be built. The next N lines each contain an ordered pair xi and yi, giving the Cartesian coordinates of the nodes. Then follow M lines each containing two integers i and j between 1 and N (inclusive) meaning a wire can be built between node i and node j for unidirectional command delivery from the former to the latter. littleken’s headquarter is always located at node 1. Process to end of file.
Output
For each test case, output exactly one line containing the shortest total length of wires to two digits past the decimal point. In the cases that such a network does not exist, just output ‘poor snoopy
’.
Sample Input
4 6 0 6 4 6 0 0 7 20 1 2 1 3 2 3 3 4 3 1 3 2 4 3 0 0 1 0 0 1 1 2 1 3 4 1 2 3
Sample Output
31.19 poor snoopy
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; #define MAXN 110 #define inf 1000000000 struct Node { double x; double y; }node[MAXN]; int n, m; bool visited[MAXN], circle[MAXN]; int pre[MAXN]; double graph[MAXN][MAXN]; inline double dist(int i, int j) { return sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x) + (node[i].y - node[j].y)*(node[i].y - node[j].y)); } inline double min(double a, double b) { if ( a < b)return a; return b; } void dfs(int u) //深搜,判断是否存在最小树形图 ,根是否可达每个结点 { int i; if (visited[u])return; visited[u] = true; for (i = 1; i <= n; i++)if (!visited[i] && graph[u][i] != inf)dfs(i); } bool connect(int root) //深搜,判断是否存在最小树形图 ,根是否可达每个结点 { int i; dfs(root); for (i = 1; i <= n; i++)if (!visited[i])return false; return true; } //--------------------------朱刘算法 double zhuliu(int root) { int i, j, k; double ans = 0; memset(circle,0,sizeof(circle)); //如果某点被删掉,那么circle[i]=1 while (1) { //-----------------求出除根点为root外的所有点的入边的最小值 for (i = 1; i <= n; i++) { if(i==root)continue; if (circle[i])continue; graph[i][i] = inf; //把图中所有的自环全都清除,很重要!!! pre[i] = i; //初始化自己的前一节点是自己 for (j = 1; j <= n; j++) // 求i的入边的最小值 { if (circle[j])continue; if (graph[j][i] < graph[pre[i]][i])pre[i] = j; } } //-------------------遍历找环 for (i = 1; i <= n; i++) { if(i==root)continue; if (circle[i])continue; j = i; memset(visited,false,sizeof(visited)); while (!visited[j] && j != root) { visited[j] = true; j = pre[j]; } if (j == root)continue;//j==root说明i不在环上 i = j; //找到了环 ans += graph[pre[i]][i]; for (j = pre[i]; j != i; j = pre[j]) { ans += graph[pre[j]][j]; circle[j] = 1; //用环上一点i代表此环,其他点删去,即circle[j]=1 } //判断环外的每个点A是否与环中的某个点B相连,若是相连的则改变其权值,变为graph<A,B>-graph<pre[B],B> for (j = 1; j <= n; j++) { if (circle[j])continue; if (graph[j][i] != inf)graph[j][i] -= graph[pre[i]][i]; //更新j的入边 } for (j = pre[i]; j != i; j = pre[j]) //环上所有点的最优边为人工顶点的边 { for (k = 1; k <= n; k++) { if (circle[k])continue; if (graph[j][k] != inf)graph[i][k] = min(graph[i][k],graph[j][k]); if (graph[k][j] != inf)graph[k][i] = min(graph[k][i],graph[k][j] - graph[pre[j]][j]); } } break; } if (i > n) { for (j = 1; j <= n; j++) //新图树形图的权加环的权 { if(j==root)continue; if (circle[j])continue; ans += graph[pre[j]][j]; } break; } } return ans; } int main() { int i, j, u, v; // freopen("in.txt","r",stdin); while(scanf("%d %d",&n,&m) != EOF) { for (i = 1; i <= n; i++)scanf("%lf %lf",&node[i].x,&node[i].y); for (i = 1; i <= n; i++)for (j = 1; j <= n; j++)graph[i][j] = inf; while (m--) { scanf("%d %d",&u,&v); graph[u][v] = dist(u,v); } memset(visited,false,sizeof(visited)); int root=1; if (!connect(root))printf("poor snoopy\n"); else printf("%.2lf\n",zhuliu(root)); } return 0; }
相关推荐
北大POJ初级-图算法 解题报告+AC代码
北大POJ初级-基本算法 解题报告+AC代码
北大POJ中级-基本算法 解题报告+AC代码
整理的acm知识分类 ACM-POJ 算法训练指南
NULL 博文链接:https://128kj.iteye.com/blog/1705139
POJ水题集-----50道左右-----增加自信啊..
北大POJ2531-Network Saboteur 解题报告+AC代码
NULL 博文链接:https://128kj.iteye.com/blog/1704752
NULL 博文链接:https://200830740306.iteye.com/blog/603493
北大POJ3292-Semi-prime H-numbers 解题报告+AC代码
非常全的poj答案库 1164-1874 1000-4007
【二分图顶点覆盖->最小割->最大流->Dinic算法求解】 解题报告+AC代码 http://hi.csdn.net/!s/WKVPR0 ----> 我的所有POJ解题报告 http://blog.csdn.net/lyy289065406/article/details/6642573
北大POJ1459-Power Network 解题报告+AC代码
POJ题目分类,列出了所有的类目,里面写了一些很好的框架。
poj上的算法题目分类,对于大家想练习算法的同鞋可以参考一下,里面按类列出了各种算法的题号。
北大POJ2002-Squares 解题报告+AC代码
解决算法问题 poj1082, poj1150, poj1180, poj1201, poj1222,代码完成所给题目要求。
北大POJ2305-Basic remains POJ2305-Basic remains
北大POJ3253-POJ3253-Fence Repair【STL优先队列】 解题报告+AC代码
北大POJ1321-Chess Problem POJ1321-Chess Problem