题意:求链接所有点的最短路径。
分析:最小生成树,kruskal.嗨。居然wa了2次。受不了啊。
View Code
// I'm lanjiangzhou //C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <time.h> //C++ #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cctype> #include <stack> #include <string> #include <list> #include <queue> #include <map> #include <vector> #include <deque> #include <set> using namespace std; //*************************OUTPUT************************* #ifdef WIN32 #define INT64 "%I64d" #define UINT64 "%I64u" #else #define INT64 "%lld" #define UINT64 "%llu" #endif //**************************CONSTANT*********************** #define INF 0x3f3f3f3f #define eps 1e-8 #define PI acos(-1.) #define PI2 asin (1.); typedef long long LL; //typedef __int64 LL; //codeforces typedef unsigned int ui; typedef unsigned long long ui64; #define MP make_pair typedef vector<int> VI; typedef pair<int, int> PII; #define pb push_back #define mp make_pair //***************************SENTENCE************************ #define CL(a,b) memset (a, b, sizeof (a)) #define sqr(a,b) sqrt ((double)(a)*(a) + (double)(b)*(b)) #define sqr3(a,b,c) sqrt((double)(a)*(a) + (double)(b)*(b) + (double)(c)*(c)) //****************************FUNCTION************************ template <typename T> double DIS(T va, T vb) { return sqr(va.x - vb.x, va.y - vb.y); } template <class T> inline T INTEGER_LEN(T v) { int len = 1; while (v /= 10) ++len; return len; } template <typename T> inline T square(T va, T vb) { return va * va + vb * vb; } // aply for the memory of the stack //#pragma comment (linker, "/STACK:1024000000,1024000000") //end int n; const int maxn = 10010; struct edge{ int u,v; double w; }edges[maxn]; double sum,maxedge; int pa[maxn]; int ans[maxn]; double sumweight; int m; double x[maxn],y[maxn]; int cmp(const void*a,const void*b){ edge aa=*(const edge*)a; edge bb=*(const edge*)b; //return aa.w-bb.w; if(aa.w>bb.w) return 1; else return -1; } void UFset(){ for(int i=0;i<n;i++){ pa[i]=-1; } } int findset(int x){ int s; for(s=x;pa[s]>=0;s=pa[s]); while(s!=x){ int tmp=pa[x]; pa[x]=s; x=tmp; } return s; } //合并 void Union(int R1,int R2){ int r1=findset(R1), r2=findset(R2); int tmp=pa[r1]+pa[r2]; if(pa[r1]>pa[r2]){ pa[r1]=r2; pa[r2]=tmp; } else { pa[r2]=r1; pa[r1]=tmp; } } void Kruskal(){ int num=0;//已选用边的数目 int u,v; UFset(); for(int i=0;i<m;i++){ u=edges[i].u; v=edges[i].v; if(findset(u)!=findset(v)){ sumweight+=edges[i].w; num++; Union(u,v); } if(num>=n-1) break; } } int main(){ while(scanf("%d",&n)!=EOF){ double d; int mi=0; for(int i=0;i<n;i++){ scanf("%lf%lf",&x[i],&y[i]); } for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); edges[mi].u=i; edges[mi].v=j; edges[mi].w=d; mi++; } } m=mi; qsort(edges,m,sizeof(edges[0]),cmp); sumweight=0.0; Kruskal(); printf("%.2lf\n",sumweight); } return 0; }