Command NetworkTime limit:1000ms Memory Limit:131072ktotal submissions:13398Accepted:3868description
After a long lasting war in words, a war on arms finally breaks out between Littleken ' s and Knuthocean ' s kingdoms. A sudden and violent assault by Knuthocean's force have 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, and the most urgent point was to enable Littenken ' s commands t o Reach every disconnected node in the destroyed network and decides on a plan to build a unidirectional communication net Work. The nodes is distributed on a plane. If Littleken ' s commands is to being able to being delivered directly from a node-to-another node B, a wire would has to be BU Ilt along the straight line segment connecting the nodes. Since It's in wartime, not between all pairs of the nodes can wires be built. Snoopy wants the plan to require, the shortest total, length of wires so, the construction can is done very soon.
Input
The input contains several test cases. Each test case is starts with a line containing the 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 II integers I and J between 1 and N (inclusive) meaning a wire can be built between N Ode I and Node J for unidirectional command delivery from the former to the latter. Littleken ' s headquarter is all 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 the digits past the decimal p Oint. In the cases this 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
Source
POJ monthly--2006.12.31, Galaxy
The main idea: After a long war, a war finally cut off the ties between the Littleken and the Knuthocean kingdoms.
Littleken's command network is paralyzed, and the most important thing now is to create a temporary communications network that
to the Snoopy.
Snoopy felt that the most important point was to send the command to every dot in the destroyed network, so he decided to first
Establish a one-way transport network. Assume that all transport nodes are distributed on a single plane. If Littleken's
command to transfer from Node A to Node B, a one-way cable must be established to connect from Node A to Node B. In order to
Save as much resources as possible, requiring minimal cable lengths for communication networks (refer to ACM-ICPC Programming series).
Now give you n point coordinates (x, y), M can erect a path to the cable. At least the required cable length. If
Cannot establish such a communication network, the output "poor Snoopy".
Idea: After understanding the meaning of the topic, it is converted to give you a graph of the smallest tree of the graph. It's here to use
To Zhu Liu algorithm (finally see our Chinese wrote the algorithm). The steps are as follows:
Zhu Liu Algorithm (Edmonds) :
Based on the idea of greed and shrinking points.
Assume that the root vertex is V0.
(1) In addition to the root node, all point VI, find the shortest side with VI as the end point, join the collection
(Pre[v] Stores the starting point of the end Point V, In[v] stores the shortest edge of the terminal V)
(2) Check that there are no forward loops and shrinkage points in the set. If there is no direction ring and contraction point, end calculation; if there is no Shang,
But with a shrinking edge, skip to step (4), or skip to step (3) If it contains a forward loop.
(3) contains a direction ring, then the contraction has Shang (contraction point), the ring is shrunk to a point, the side of the ring is shrunk, while the outer edge is insured
To build a new diagram, repeat steps (1), (2).
(4) There is no forward ring, there is a shrinking edge, then expand the shrinking edge.
It is necessary to have a picture.
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include < Cmath> #include <limits.h>using namespace std;const int maxn = 110;const int MAXM = 10010;struct node{int from; int to; Double W;}; Node edges[maxm];struct node1{Double x; Double y;}; Node1 POINT[MAXN];d ouble Dist (Node1 A, Node1 b) {double x = a.x-b.x; Double y = a.y-b.y; return sqrt (x*x+y*y);} int PRE[MAXN],VIS[MAXN],FLAG[MAXN];d ouble in[maxn],sum;double zhuliu (int root,int n,int M) {sum = 0; while (true) {for (int i = 0; i < N; ++i) in[i] = Int_max; for (int i = 0; i < M; ++i) {int u = edges[i].from; int v = edges[i].to; if (EDGES[I].W < in[v] && u! = V) {Pre[v] = u;//v as end point, Pre[v] store starting point In[v] = edges[i].w;//of the least-weighted side} for (int i = 0; i < N; ++i)//If there are outliers other than root, no minimum tree diagram exists. { if (i = = root) continue; if (in[i] = = Int_max) return-1; } int cntnode = 0; memset (flag,-1,sizeof (flag)); memset (vis,-1,sizeof (VIS)); In[root] = 0; for (int i = 0; i < N; ++i)//Find ring, mark each ring {sum + = In[i]; int v = i; while (vis[v]!=i && flag[v]==-1 && v!=root)//each point looks for its pre-order point, either eventually finding the root, or finding a ring {vis[ V] = i; v = pre[v]; if (v! = root && flag[v] = =-1)//new figure Renumber {for (int u = pre[v]; u! = V; u = Pre[u]) flag[u] = Cntnode; FLAG[V] = cntnode++; }} if (Cntnode = = 0)//no ring, jump out of break; for (int i = 0; i < N; ++i) {if (flag[i] = = 1) flag[i] = cntnode++; } for (int i = 0; i < M; ++i)//Create new diagram, update other points to ring distance {int v = Edges[i].to; Edges[i].from = Flag[edges[i].from]; Edges[i].to = flag[edges[i].to]; if (edges[i].from! = edges[i].to) EDGES[I].W-= In[v]; } N = Cntnode; root = Flag[root]; } return sum;} int main () {int x,y,n,m; while (~SCANF ("%d%d", &n,&m)) {int id = 0; for (int i = 0; i < N; ++i) scanf ("%lf%lf", &point[i].x,&point[i].y); for (int i = 0; i < M; ++i) {scanf ("%d%d", &x,&y); if (x = = y) continue; x--; y--; Edges[id].from = x; edges[id].to = y; EDGES[ID++].W = Dist (Point[x],point[y]); } Double ans = Zhuliu (0,n,id); if (ans = =-1) printf ("Poor snoopy\n"); else printf ("%.2lf\n", ans); } return 0;}
POJ3164 Command Network "minimum tree Diagram" "Zhu Liu Algorithm"