题意:要求建立司令部到各个欧几里德平面上的节点,给定可建立的顶点对(u,v)  =  u 可建立单向信道至 v ,求司令部形成对所有节点的指挥需要的最小建设花费。
      算法:最小图形树,不解释~ 
 1 /*
/*
 2 Problem: 3164        User: _mTy
Problem: 3164        User: _mTy
 3 Memory: 872K        Time: 172MS
Memory: 872K        Time: 172MS
 4 Language: C++        Result: Accepted
Language: C++        Result: Accepted
 5
 6 Source Code
Source Code
 7 */
*/
 8 #include<cstdio>
#include<cstdio>
 9 #include <cstring>
#include <cstring>
10 #include<cmath>
#include<cmath>
11 #define MAXN 120
#define MAXN 120
12 #define inf 1000000000
#define inf 1000000000
13 typedef double elem_t;
typedef double elem_t;
14 elem_t edmonds(int n,elem_t mat[][MAXN*2],int* pre);
elem_t edmonds(int n,elem_t mat[][MAXN*2],int* pre);
15 int main(){
int main(){
16 elem_t point[MAXN][2];
    elem_t point[MAXN][2];
17 elem_t mat[MAXN*2][MAXN*2];
    elem_t mat[MAXN*2][MAXN*2];
18 elem_t res,len;
    elem_t res,len;
19 int pre[MAXN];
    int pre[MAXN];
20 int i,j,n,m,u,v;
    int i,j,n,m,u,v;
21
22 while(scanf("%d%d",&n,&m)!=EOF){
    while(scanf("%d%d",&n,&m)!=EOF){
23 for(i=0;i<n;i++) for(j=0;j<n;j++) mat[i][j]=inf;
        for(i=0;i<n;i++) for(j=0;j<n;j++) mat[i][j]=inf;
24 for(i=0;i<n;i++) scanf("%lf%lf",&point[i][0],&point[i][1]);
        for(i=0;i<n;i++) scanf("%lf%lf",&point[i][0],&point[i][1]);
25 for(i=0;i<m;i++){
        for(i=0;i<m;i++){
26 scanf("%d%d",&u,&v); --u; --v;
            scanf("%d%d",&u,&v); --u; --v;
27 len = pow(point[u][0]-point[v][0],2)+pow(point[u][1]-point[v][1],2);
            len = pow(point[u][0]-point[v][0],2)+pow(point[u][1]-point[v][1],2);
28
29 len = sqrt(len);
            len = sqrt(len);
30 mat[u][v]=len;
            mat[u][v]=len;
31 }
        }
32
33 memset(pre,0,sizeof(pre));
        memset(pre,0,sizeof(pre));
34 pre[0]=-1;
        pre[0]=-1;
35 res = edmonds(n,mat,pre);
        res = edmonds(n,mat,pre);
36 if(res<0) printf("poor snoopy\n");
        if(res<0) printf("poor snoopy\n");
37 else printf("%.2f\n",res);
        else printf("%.2f\n",res);
38 }
    }
39 return 0;
    return 0;
40 }
}
41
42 //多源最小树形图,edmonds算法,邻接阵形式,复杂度O(n^3)
//多源最小树形图,edmonds算法,邻接阵形式,复杂度O(n^3)
43 //返回最小生成树的长度,构造失败返回负值
//返回最小生成树的长度,构造失败返回负值
44 //传入图的大小n和邻接阵mat,不相邻点边权inf
//传入图的大小n和邻接阵mat,不相邻点边权inf
45 //可更改边权的类型,pre[]返回树的构造,用父结点表示
//可更改边权的类型,pre[]返回树的构造,用父结点表示
46 //传入时pre[]数组清零,用-1标出源点
//传入时pre[]数组清零,用-1标出源点
47
48 elem_t edmonds(int n,elem_t mat[][MAXN*2],int* pre){
elem_t edmonds(int n,elem_t mat[][MAXN*2],int* pre){
49 elem_t ret=0;
    elem_t ret=0;
50 int c[MAXN*2][MAXN*2],l[MAXN*2],p[MAXN*2],m=n,t,i,j,k;
    int c[MAXN*2][MAXN*2],l[MAXN*2],p[MAXN*2],m=n,t,i,j,k;
51 for (i=0;i<n;l[i]=i,i++);
    for (i=0;i<n;l[i]=i,i++);
52 do{
    do{
53 memset(c,0,sizeof(c)),memset(p,0xff,sizeof(p));
        memset(c,0,sizeof(c)),memset(p,0xff,sizeof(p));
54 for (t=m,i=0;i<m;c[i][i]=1,i++);
        for (t=m,i=0;i<m;c[i][i]=1,i++);
55 for (i=0;i<t;i++)
        for (i=0;i<t;i++)
56 if (l[i]==i&&pre[i]!=-1){
            if (l[i]==i&&pre[i]!=-1){
57 for (j=0;j<m;j++)
                for (j=0;j<m;j++)
58 if (l[j]==j&&i!=j&&mat[j][i]<inf&&(p[i]==-1||mat[j][i]<mat[p[i]][i]))
                    if (l[j]==j&&i!=j&&mat[j][i]<inf&&(p[i]==-1||mat[j][i]<mat[p[i]][i]))
59 p[i]=j;
                        p[i]=j;
60 if ((pre[i]=p[i])==-1)
                if ((pre[i]=p[i])==-1)
61 return -1;
                    return -1;
62 if (c[i][p[i]]){
                if (c[i][p[i]]){
63 for (j=0;j<=m;mat[j][m]=mat[m][j]=inf,j++);
                    for (j=0;j<=m;mat[j][m]=mat[m][j]=inf,j++);
64 for (k=i;l[k]!=m;l[k]=m,k=p[k])
                    for (k=i;l[k]!=m;l[k]=m,k=p[k])
65 for (j=0;j<m;j++)
                        for (j=0;j<m;j++)
66 if (l[j]==j){
                            if (l[j]==j){
67 if (mat[j][k]-mat[p[k]][k]<mat[j][m])
                                if (mat[j][k]-mat[p[k]][k]<mat[j][m])
68 mat[j][m]=mat[j][k]-mat[p[k]][k];
                                    mat[j][m]=mat[j][k]-mat[p[k]][k];
69 if (mat[k][j]<mat[m][j])
                                if (mat[k][j]<mat[m][j])
70 mat[m][j]=mat[k][j];
                                    mat[m][j]=mat[k][j];
71 }
                            }
72 c[m][m]=1,l[m]=m,m++;
                    c[m][m]=1,l[m]=m,m++;
73 }
                }
74 for (j=0;j<m;j++)
                for (j=0;j<m;j++)
75 if (c[i][j])
                    if (c[i][j])
76 for (k=p[i];k!=-1&&l[k]==k;c[k][j]=1,k=p[k]);
                        for (k=p[i];k!=-1&&l[k]==k;c[k][j]=1,k=p[k]);
77 }
            }
78 }
    }
79 while (t<m);
    while (t<m);
80 for (;m-->n;pre[k]=pre[m])
    for (;m-->n;pre[k]=pre[m])
81 for (i=0;i<m;i++)
        for (i=0;i<m;i++)
82 if (l[i]==m){
            if (l[i]==m){
83 for (j=0;j<m;j++)
                for (j=0;j<m;j++)
84 if (pre[j]==m&&mat[i][j]==mat[m][j])
                    if (pre[j]==m&&mat[i][j]==mat[m][j])
85 pre[j]=i;
                        pre[j]=i;
86 if (mat[pre[m]][m]==mat[pre[m]][i]-mat[pre[i]][i])
                if (mat[pre[m]][m]==mat[pre[m]][i]-mat[pre[i]][i])
87 k=i;
                    k=i;
88 }
            }
89 for (i=0;i<n;i++)
    for (i=0;i<n;i++)
90 if (pre[i]!=-1)
        if (pre[i]!=-1)
91 ret+=mat[pre[i]][i];
            ret+=mat[pre[i]][i];
92 return ret;
    return ret;
93 }
}