Description
Awson是某国际学校信竞组的一只菜鸡。他们班主任F老师喜欢带他们去爬爬唷喽山。登顶后,Awson有了个奇怪的发现。
山腰上有N(1<=N<=100)个村庄,这些村庄可以用平面坐标(X,Y)刻画。假设要给这N个村庄供水。已知1号村庄内有一个处理水厂, 从此处可以输水给其他各个村庄。现在给出M(1<=M<=10000)种修水渠的方案,每种方案的水渠连接两个村庄U,V。由于地势等其他原 因,水的运输是单向的,即只能从U运输到V。水渠是笔直的,即水渠的长度就是U,V两村庄的欧式距离。因为Awson是一个善于发现问题、提出问题,但不 喜欢解决问题的人。所以他找到了你,烦请你设计出能够将水输送到所有村庄的方案,并且使水渠总长度最小。
Input
第1行:两个整数,N,M。
接下来N行,每行两个整数,第i行Xi,Yi,表示村庄的坐标。
再接下来M行,每行两个整数,第i行Ui,Vi,表示Ui,Vi两村庄间有一条从Ui到Vi的修水渠方案。
Output
共1行,1个整数,表示使所有机房连上网的费用最小值。
Sample Input1
4 60 64 60 07 201 21 32 33 43 13 2
Sample Output1
31.19
Sample Input2
4 3 0 0 1 0 0 1 1 2 1 3 4 1 2 3
Sample Output2
poor Awson
Hint
样例解释:
对于样例1:选择第1、2、4方案,长度最小,其为31.19;
对于样例2:没有方案使其连通。
数据规模:
40%的数据:1<=N<=50,1<=M<=2500;
100%的数据:1<=N<=100,1<=M<=10000,1<=X,Y<=10000,数据不保证无自环,不保证无重边、回边。
题解
朱刘算法裸题,当模板存着。
1 #include<map> 2 #include<queue> 3 #include<stack> 4 #include<vector> 5 #include<ctime> 6 #include<cmath> 7 #include<cstdio> 8 #include<string> 9 #include<cstdlib> 10 #include<cstring> 11 #include<iostream> 12 #include<algorithm> 13 using namespace std; 14 const int N=100; 15 16 struct node 17 { 18 int x,y; 19 }pos[N+5]; 20 struct tt 21 { 22 int u,v; 23 double c; 24 }edge[N*N+5]; 25 int n,m,u,v; 26 inline double Dist(int u,int v); 27 28 double in[N+5]; 29 int vis[N+5]; 30 int pre[N+5]; 31 int id[N+5],cnt; 32 double ZLEdmons(); 33 34 int main() 35 { 36 scanf("%d%d",&n,&m); 37 for (int i=1;i<=n;i++) scanf("%d%d",&pos[i].x,&pos[i].y); 38 bool in[N+5]={0}; 39 for (int i=1;i<=m;i++) 40 { 41 scanf("%d%d",&u,&v); 42 edge[i].v=v; 43 edge[i].u=u; 44 edge[i].c=Dist(u,v); 45 in[v]=1; 46 } 47 for (int i=1;i<=n;i++) if (!in[i]) 48 { 49 printf("poor Awson\n"); 50 return 0; 51 } 52 printf("%.2lf\n",ZLEdmons()); 53 return 0; 54 } 55 56 inline double Dist(int u,int v){return sqrt((pos[u].x-pos[v].x)*(pos[u].x-pos[v].x)+(pos[u].y-pos[v].y)*(pos[u].y-pos[v].y));} 57 double ZLEdmons() 58 { 59 double ans=0; 60 int root=1; 61 while (true) 62 { 63 memset(in,127,sizeof(in)); 64 for (int i=1;i<=m;i++) 65 { 66 if (edge[i].c<in[edge[i].v]&&edge[i].u!=edge[i].v) 67 { 68 in[edge[i].v]=edge[i].c; 69 pre[edge[i].v]=edge[i].u; 70 } 71 } 72 in[root]=0; 73 int cnt=0; 74 memset(id,-1,sizeof(id)); 75 memset(vis,-1,sizeof(vis)); 76 for (int i=1;i<=n;i++) 77 { 78 ans+=in[i]; 79 v=i; 80 while (vis[v]!=i&&v!=root&&id[v]==-1) 81 { 82 vis[v]=i; 83 v=pre[v]; 84 } 85 if (v!=root&&id[v]==-1) 86 { 87 id[v]=++cnt; 88 for (int u=pre[v];u!=v;u=pre[u]) id[u]=cnt; 89 } 90 } 91 if (cnt==0) break; 92 for (int i=1;i<=n;i++) if (id[i]==-1) id[i]=++cnt; 93 for (int i=1;i<=m;i++) 94 { 95 v=edge[i].v; 96 edge[i].u=id[edge[i].u]; 97 edge[i].v=id[edge[i].v]; 98 if (edge[i].u!=edge[i].v) edge[i].c-=in[v]; 99 } 100 n=cnt; 101 root=id[root]; 102 } 103 return ans; 104 }
时间: 2024-11-07 07:17:19