最小生成树
poj1251 http://poj.org/problem?id=1251
prim
1 #include<cstdio> 2 const int inf=0x3f3f3f3f; 3 class Prim{///最小生成树(无向图)o(MV^2)要保证图连通 4 typedef int typec;///边权的类型 5 static const int MV=32;///点的个数 6 int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1 7 bool vis[MV]; 8 typec mat[MV][MV],dist[MV],res; 9 public: 10 void init(int tn){///传入点数,点下标0开始 11 n=tn; 12 for(i=0;i<n;i++) 13 for(j=0;j<n;j++) 14 mat[i][j]=i==j?0:inf;///不相邻点边权inf 15 } 16 void add(int u,int v,typec w){ 17 if(mat[u][v]>w){ 18 mat[u][v]=w; 19 mat[v][u]=w; 20 } 21 } 22 int solve(){///返回最小生成树的长度 23 for(res=i=0;i<n;i++){ 24 dist[i]=inf; 25 vis[i]=false; 26 pre[i]=-1; 27 } 28 for(dist[j=0]=0;j<n;j++){ 29 for(k=-1,i=0;i<n;i++){ 30 if(!vis[i]&&(k==-1||dist[i]<dist[k])){ 31 k=i; 32 } 33 } 34 for(vis[k]=true,res+=dist[k],i=0;i<n;i++){ 35 if(!vis[i]&&mat[k][i]<dist[i]){ 36 dist[i]=mat[pre[i]=k][i]; 37 } 38 } 39 } 40 return res; 41 } 42 }gx; 43 int main() { 44 int n; 45 char op[4]; 46 while(~scanf("%d",&n),n){ 47 gx.init(n); 48 for(int i=0,num,val;i<n-1;i++){ 49 scanf("%s%d",op,&num); 50 while(num--){ 51 scanf("%s%d",op,&val); 52 gx.add(i,op[0]-'A',val); 53 gx.add(op[0]-'A',i,val); 54 } 55 } 56 printf("%d\n",gx.solve()); 57 } 58 return 0; 59 }
kruskal
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 const int M=1010; 8 class Kruskal { ///最小生成树(无向图)o(ME*logME) 9 typedef int typec;///边权的类型 10 static const int ME=1024;///边的个数 11 static const int MV=32;///点的个数 12 class UnionFindSet { ///并查集 13 int par[MV]; 14 public: 15 void init() { 16 mt(par,-1); 17 } 18 int getroot(int x) { 19 int i=x,j=x,temp; 20 while(par[i]>=0) i=par[i]; 21 while(j!=i) { 22 temp=par[j]; 23 par[j]=i; 24 j=temp; 25 } 26 return i; 27 } 28 bool unite(int x,int y) { 29 int p=getroot(x); 30 int q=getroot(y); 31 if(p==q)return false; 32 if(par[p]>par[q]) { 33 par[q]+=par[p]; 34 par[p]=q; 35 } else { 36 par[p]+=par[q]; 37 par[q]=p; 38 } 39 return true; 40 } 41 } f; 42 struct E { 43 int u,v; 44 typec w; 45 friend bool operator < (E a,E b) { 46 return a.w<b.w; 47 } 48 } e[ME]; 49 int le,num,n; 50 typec res; 51 public: 52 void init(int tn){///传入点的个数 53 n=tn; 54 le=res=0; 55 f.init(); 56 num=1; 57 } 58 void add(int u,int v,int w) { 59 e[le].u=u; 60 e[le].v=v; 61 e[le].w=w; 62 le++; 63 } 64 typec solve(){///返回-1不连通 65 sort(e,e+le); 66 for(int i=0; i<le&&num<n; i++) { 67 if(f.unite(e[i].u,e[i].v)) { 68 num++; 69 res+=e[i].w; 70 } 71 } 72 if(num<n) res=-1; 73 return res; 74 } 75 }gx; 76 int main() { 77 int n; 78 char op[4]; 79 while(~scanf("%d",&n),n) { 80 gx.init(n); 81 for(int i=0,num,val; i<n-1; i++) { 82 scanf("%s%d",op,&num); 83 while(num--) { 84 scanf("%s%d",op,&val); 85 gx.add(i,op[0]-'A',val); 86 } 87 } 88 printf("%d\n",gx.solve()); 89 } 90 return 0; 91 }
poj1258 http://poj.org/problem?id=1258
prim
1 #include<cstdio> 2 const int inf=0x3f3f3f3f; 3 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通 4 typedef int typec;///边权的类型 5 static const int MV=128;///点的个数 6 int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1 7 bool vis[MV]; 8 typec mat[MV][MV],dist[MV],res; 9 public: 10 void init(int tn) { ///传入点数,点下标0开始 11 n=tn; 12 for(i=0; i<n; i++) 13 for(j=0; j<n; j++) 14 mat[i][j]=i==j?0:inf;///不相邻点边权inf 15 } 16 void add(int u,int v,typec w) { 17 if(mat[u][v]>w) { 18 mat[u][v]=w; 19 mat[v][u]=w; 20 } 21 } 22 int solve() { ///返回最小生成树的长度 23 for(res=i=0; i<n; i++) { 24 dist[i]=inf; 25 vis[i]=false; 26 pre[i]=-1; 27 } 28 for(dist[j=0]=0; j<n; j++) { 29 for(k=-1,i=0; i<n; i++) { 30 if(!vis[i]&&(k==-1||dist[i]<dist[k])) { 31 k=i; 32 } 33 } 34 for(vis[k]=true,res+=dist[k],i=0; i<n; i++) { 35 if(!vis[i]&&mat[k][i]<dist[i]) { 36 dist[i]=mat[pre[i]=k][i]; 37 } 38 } 39 } 40 return res; 41 } 42 }gx; 43 int main(){ 44 int n; 45 while(~scanf("%d",&n)){ 46 gx.init(n); 47 for(int i=0,w;i<n;i++){ 48 for(int j=0;j<n;j++){ 49 scanf("%d",&w); 50 gx.add(i,j,w); 51 } 52 } 53 printf("%d\n",gx.solve()); 54 } 55 return 0; 56 }
kruskal
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 class Kruskal { ///最小生成树(无向图)o(ME*logME) 7 typedef int typec;///边权的类型 8 static const int ME=10010;///边的个数 9 static const int MV=128;///点的个数 10 class UnionFindSet { ///并查集 11 int par[MV]; 12 public: 13 void init() { 14 mt(par,-1); 15 } 16 int getroot(int x) { 17 int i=x,j=x,temp; 18 while(par[i]>=0) i=par[i]; 19 while(j!=i) { 20 temp=par[j]; 21 par[j]=i; 22 j=temp; 23 } 24 return i; 25 } 26 bool unite(int x,int y) { 27 int p=getroot(x); 28 int q=getroot(y); 29 if(p==q)return false; 30 if(par[p]>par[q]) { 31 par[q]+=par[p]; 32 par[p]=q; 33 } else { 34 par[p]+=par[q]; 35 par[q]=p; 36 } 37 return true; 38 } 39 } f; 40 struct E { 41 int u,v; 42 typec w; 43 friend bool operator < (E a,E b) { 44 return a.w<b.w; 45 } 46 } e[ME]; 47 int le,num,n; 48 typec res; 49 public: 50 void init(int tn){///传入点的个数 51 n=tn; 52 le=res=0; 53 f.init(); 54 num=1; 55 } 56 void add(int u,int v,typec w) { 57 e[le].u=u; 58 e[le].v=v; 59 e[le].w=w; 60 le++; 61 } 62 typec solve(){///返回-1不连通 63 sort(e,e+le); 64 for(int i=0; i<le&&num<n; i++) { 65 if(f.unite(e[i].u,e[i].v)) { 66 num++; 67 res+=e[i].w; 68 } 69 } 70 if(num<n) res=-1; 71 return res; 72 } 73 }gx; 74 int main(){ 75 int n; 76 while(~scanf("%d",&n)){ 77 gx.init(n); 78 for(int i=0,w;i<n;i++){ 79 for(int j=0;j<n;j++){ 80 scanf("%d",&w); 81 if(i<j){ 82 gx.add(i,j,w); 83 } 84 } 85 } 86 printf("%d\n",gx.solve()); 87 } 88 return 0; 89 }
poj1789 http://poj.org/problem?id=1789
prim
1 #include<cstdio> 2 const int inf=0x3f3f3f3f; 3 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通 4 typedef int typec;///边权的类型 5 static const int MV=2048;///点的个数 6 int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1 7 bool vis[MV]; 8 typec mat[MV][MV],dist[MV],res; 9 public: 10 void init(int tn) { ///传入点数,点下标0开始 11 n=tn; 12 for(i=0; i<n; i++) 13 for(j=0; j<n; j++) 14 mat[i][j]=i==j?0:inf;///不相邻点边权inf 15 } 16 void add(int u,int v,typec w) { 17 if(mat[u][v]>w) { 18 mat[u][v]=w; 19 mat[v][u]=w; 20 } 21 } 22 int solve() { ///返回最小生成树的长度 23 for(res=i=0; i<n; i++) { 24 dist[i]=inf; 25 vis[i]=false; 26 pre[i]=-1; 27 } 28 for(dist[j=0]=0; j<n; j++) { 29 for(k=-1,i=0; i<n; i++) { 30 if(!vis[i]&&(k==-1||dist[i]<dist[k])) { 31 k=i; 32 } 33 } 34 for(vis[k]=true,res+=dist[k],i=0; i<n; i++) { 35 if(!vis[i]&&mat[k][i]<dist[i]) { 36 dist[i]=mat[pre[i]=k][i]; 37 } 38 } 39 } 40 return res; 41 } 42 }gx; 43 struct S{ 44 char s[8]; 45 }str[2048]; 46 int main(){ 47 int n; 48 while(~scanf("%d",&n),n){ 49 gx.init(n); 50 for(int i=0;i<n;i++){ 51 scanf("%s",str[i].s); 52 } 53 for(int i=0;i<n;i++){ 54 for(int j=i+1;j<n;j++){ 55 int val=0; 56 for(int k=0;k<7;k++){ 57 if(str[i].s[k]!=str[j].s[k]){ 58 val++; 59 } 60 } 61 gx.add(i,j,val); 62 } 63 } 64 printf("The highest possible quality is 1/%d.\n",gx.solve()); 65 } 66 return 0; 67 }
kruskal
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 class Kruskal { ///最小生成树(无向图)o(ME*logME) 8 typedef int typec;///边权的类型 9 static const int ME=4000010;///边的个数 10 static const int MV=2048;///点的个数 11 class UnionFindSet { ///并查集 12 int par[MV]; 13 public: 14 void init() { 15 mt(par,-1); 16 } 17 int getroot(int x) { 18 int i=x,j=x,temp; 19 while(par[i]>=0) i=par[i]; 20 while(j!=i) { 21 temp=par[j]; 22 par[j]=i; 23 j=temp; 24 } 25 return i; 26 } 27 bool unite(int x,int y) { 28 int p=getroot(x); 29 int q=getroot(y); 30 if(p==q)return false; 31 if(par[p]>par[q]) { 32 par[q]+=par[p]; 33 par[p]=q; 34 } else { 35 par[p]+=par[q]; 36 par[q]=p; 37 } 38 return true; 39 } 40 } f; 41 struct E { 42 int u,v; 43 typec w; 44 friend bool operator < (E a,E b) { 45 return a.w<b.w; 46 } 47 } e[ME]; 48 int le,num,n; 49 typec res; 50 public: 51 void init(int tn){///传入点的个数 52 n=tn; 53 le=res=0; 54 f.init(); 55 num=1; 56 } 57 void add(int u,int v,typec w) { 58 e[le].u=u; 59 e[le].v=v; 60 e[le].w=w; 61 le++; 62 } 63 typec solve(){///返回-1不连通 64 sort(e,e+le); 65 for(int i=0; i<le&&num<n; i++) { 66 if(f.unite(e[i].u,e[i].v)) { 67 num++; 68 res+=e[i].w; 69 } 70 } 71 if(num<n) res=-1; 72 return res; 73 } 74 }gx; 75 struct S{ 76 char s[8]; 77 }str[2048]; 78 int main(){ 79 int n; 80 while(~scanf("%d",&n),n){ 81 gx.init(n); 82 for(int i=0;i<n;i++){ 83 scanf("%s",str[i].s); 84 } 85 for(int i=0;i<n;i++){ 86 for(int j=i+1;j<n;j++){ 87 int val=0; 88 for(int k=0;k<7;k++){ 89 if(str[i].s[k]!=str[j].s[k]){ 90 val++; 91 } 92 } 93 gx.add(i,j,val); 94 } 95 } 96 printf("The highest possible quality is 1/%d.\n",gx.solve()); 97 } 98 return 0; 99 }
poj2349 http://poj.org/problem?id=2349
prim
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 const int inf=0x3f3f3f3f; 6 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通 7 typedef double typec;///边权的类型 8 static const int MV=512;///点的个数 9 int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1 10 bool vis[MV]; 11 public: 12 typec mat[MV][MV],dist[MV],res; 13 public: 14 void init(int tn) { ///传入点数,点下标0开始 15 n=tn; 16 for(i=0; i<n; i++) 17 for(j=0; j<n; j++) 18 mat[i][j]=i==j?0:inf;///不相邻点边权inf 19 } 20 void add(int u,int v,typec w) { 21 if(mat[u][v]>w) { 22 mat[u][v]=w; 23 mat[v][u]=w; 24 } 25 } 26 typec solve() { ///返回最小生成树的长度 27 for(res=i=0; i<n; i++) { 28 dist[i]=inf; 29 vis[i]=false; 30 pre[i]=-1; 31 } 32 for(dist[j=0]=0; j<n; j++) { 33 for(k=-1,i=0; i<n; i++) { 34 if(!vis[i]&&(k==-1||dist[i]<dist[k])) { 35 k=i; 36 } 37 } 38 for(vis[k]=true,res+=dist[k],i=0; i<n; i++) { 39 if(!vis[i]&&mat[k][i]<dist[i]) { 40 dist[i]=mat[pre[i]=k][i]; 41 } 42 } 43 } 44 return res; 45 } 46 }gx; 47 struct P{ 48 double x,y; 49 }p[512]; 50 int main(){ 51 int t,n,m; 52 while(~scanf("%d",&t)){ 53 while(t--){ 54 scanf("%d%d",&n,&m); 55 for(int i=0;i<m;i++){ 56 scanf("%lf%lf",&p[i].x,&p[i].y); 57 } 58 gx.init(m); 59 for(int i=0;i<m;i++){ 60 for(int j=0;j<m;j++){ 61 gx.add(i,j,sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y))); 62 } 63 } 64 gx.solve(); 65 sort(gx.dist,gx.dist+m); 66 printf("%.2f\n",gx.dist[m-n]); 67 } 68 } 69 return 0; 70 }
kruskal
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int inf=0x3f3f3f3f; 8 double d[250010]; 9 int ld; 10 class Kruskal { ///最小生成树(无向图)o(ME*logME) 11 typedef double typec;///边权的类型 12 static const int ME=250010;///边的个数 13 static const int MV=512;///点的个数 14 class UnionFindSet { ///并查集 15 int par[MV]; 16 public: 17 void init() { 18 mt(par,-1); 19 } 20 int getroot(int x) { 21 int i=x,j=x,temp; 22 while(par[i]>=0) i=par[i]; 23 while(j!=i) { 24 temp=par[j]; 25 par[j]=i; 26 j=temp; 27 } 28 return i; 29 } 30 bool unite(int x,int y) { 31 int p=getroot(x); 32 int q=getroot(y); 33 if(p==q)return false; 34 if(par[p]>par[q]) { 35 par[q]+=par[p]; 36 par[p]=q; 37 } else { 38 par[p]+=par[q]; 39 par[q]=p; 40 } 41 return true; 42 } 43 } f; 44 struct E { 45 int u,v; 46 typec w; 47 friend bool operator < (E a,E b) { 48 return a.w<b.w; 49 } 50 } e[ME]; 51 int le,num,n; 52 typec res; 53 public: 54 void init(int tn){///传入点的个数 55 n=tn; 56 le=res=0; 57 f.init(); 58 num=1; 59 } 60 void add(int u,int v,typec w) { 61 e[le].u=u; 62 e[le].v=v; 63 e[le].w=w; 64 le++; 65 } 66 typec solve(){///返回-1不连通 67 sort(e,e+le); 68 for(int i=0; i<le&&num<n; i++) { 69 if(f.unite(e[i].u,e[i].v)) { 70 num++; 71 res+=e[i].w; 72 d[ld++]=e[i].w; 73 } 74 } 75 if(num<n) res=-1; 76 return res; 77 } 78 }gx; 79 struct P{ 80 double x,y; 81 }p[512]; 82 int main(){ 83 int t,n,m; 84 while(~scanf("%d",&t)){ 85 while(t--){ 86 scanf("%d%d",&n,&m); 87 for(int i=0;i<m;i++){ 88 scanf("%lf%lf",&p[i].x,&p[i].y); 89 } 90 gx.init(m); 91 for(int i=0;i<m;i++){ 92 for(int j=i+1;j<m;j++){ 93 gx.add(i,j,sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y))); 94 } 95 } 96 ld=0; 97 gx.solve(); 98 sort(d,d+ld); 99 printf("%.2f\n",d[m-n-1]); 100 } 101 } 102 return 0; 103 }
poj2485 http://poj.org/problem?id=2485
prim
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int inf=0x3f3f3f3f; 5 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通 6 typedef int typec;///边权的类型 7 static const int MV=512;///点的个数 8 int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1 9 bool vis[MV]; 10 public: 11 typec mat[MV][MV],dist[MV],res; 12 public: 13 void init(int tn) { ///传入点数,点下标0开始 14 n=tn; 15 for(i=0; i<n; i++) 16 for(j=0; j<n; j++) 17 mat[i][j]=i==j?0:inf;///不相邻点边权inf 18 } 19 void add(int u,int v,typec w) { 20 if(mat[u][v]>w) { 21 mat[u][v]=w; 22 mat[v][u]=w; 23 } 24 } 25 typec solve() { ///返回最小生成树的长度 26 for(res=i=0; i<n; i++) { 27 dist[i]=inf; 28 vis[i]=false; 29 pre[i]=-1; 30 } 31 for(dist[j=0]=0; j<n; j++) { 32 for(k=-1,i=0; i<n; i++) { 33 if(!vis[i]&&(k==-1||dist[i]<dist[k])) { 34 k=i; 35 } 36 } 37 for(vis[k]=true,res+=dist[k],i=0; i<n; i++) { 38 if(!vis[i]&&mat[k][i]<dist[i]) { 39 dist[i]=mat[pre[i]=k][i]; 40 } 41 } 42 } 43 return res; 44 } 45 }gx; 46 int main(){ 47 int t,n; 48 while(~scanf("%d",&t)){ 49 while(t--){ 50 scanf("%d",&n); 51 gx.init(n); 52 for(int i=0,w;i<n;i++){ 53 for(int j=0;j<n;j++){ 54 scanf("%d",&w); 55 gx.add(i,j,w); 56 } 57 } 58 gx.solve(); 59 int ans=0; 60 for(int i=1;i<n;i++){ 61 ans=max(ans,gx.dist[i]); 62 } 63 printf("%d\n",ans); 64 } 65 } 66 return 0; 67 }
kruskal
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 int ans; 8 class Kruskal { ///最小生成树(无向图)o(ME*logME) 9 typedef int typec;///边权的类型 10 static const int ME=250010;///边的个数 11 static const int MV=512;///点的个数 12 class UnionFindSet { ///并查集 13 int par[MV]; 14 public: 15 void init() { 16 mt(par,-1); 17 } 18 int getroot(int x) { 19 int i=x,j=x,temp; 20 while(par[i]>=0) i=par[i]; 21 while(j!=i) { 22 temp=par[j]; 23 par[j]=i; 24 j=temp; 25 } 26 return i; 27 } 28 bool unite(int x,int y) { 29 int p=getroot(x); 30 int q=getroot(y); 31 if(p==q)return false; 32 if(par[p]>par[q]) { 33 par[q]+=par[p]; 34 par[p]=q; 35 } else { 36 par[p]+=par[q]; 37 par[q]=p; 38 } 39 return true; 40 } 41 } f; 42 struct E { 43 int u,v; 44 typec w; 45 friend bool operator < (E a,E b) { 46 return a.w<b.w; 47 } 48 } e[ME]; 49 int le,num,n; 50 typec res; 51 public: 52 void init(int tn){///传入点的个数 53 n=tn; 54 le=res=0; 55 f.init(); 56 num=1; 57 } 58 void add(int u,int v,typec w) { 59 e[le].u=u; 60 e[le].v=v; 61 e[le].w=w; 62 le++; 63 } 64 typec solve(){///返回-1不连通 65 sort(e,e+le); 66 for(int i=0; i<le&&num<n; i++) { 67 if(f.unite(e[i].u,e[i].v)) { 68 num++; 69 res+=e[i].w; 70 ans=max(ans,e[i].w); 71 } 72 } 73 if(num<n) res=-1; 74 return res; 75 } 76 }gx; 77 int main(){ 78 int t,n; 79 while(~scanf("%d",&t)){ 80 while(t--){ 81 scanf("%d",&n); 82 gx.init(n); 83 for(int i=0,w;i<n;i++){ 84 for(int j=0;j<n;j++){ 85 scanf("%d",&w); 86 if(i<j) 87 gx.add(i,j,w); 88 } 89 } 90 ans=0; 91 gx.solve(); 92 printf("%d\n",ans); 93 } 94 } 95 return 0; 96 }
poj3026 http://poj.org/problem?id=3026
prim
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<algorithm> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int inf=0x3f3f3f3f; 8 const int M=2024; 9 int n,m; 10 struct P{ 11 int x,y; 12 }p[M*M]; 13 char a[M][M]; 14 int num[M][M]; 15 int cost[M][M]; 16 bool ispoint(char c){ 17 if(c=='S'||c=='A') return true;return false; 18 } 19 struct Q{ 20 int x,y,id,step; 21 }pre,now; 22 queue<Q> q; 23 int dx[]={0,0,1,-1}; 24 int dy[]={1,-1,0,0}; 25 bool vis[M][M]; 26 void bfs(Q now){ 27 mt(vis,0); 28 while(!q.empty()) q.pop(); 29 q.push(now); 30 vis[now.x][now.y]=true; 31 while(!q.empty()){ 32 pre=q.front(); 33 q.pop(); 34 if(ispoint(a[pre.x][pre.y])){ 35 if(cost[pre.id][num[pre.x][pre.y]]>pre.step) 36 cost[pre.id][num[pre.x][pre.y]]=pre.step; 37 } 38 for(int i=0;i<4;i++){ 39 int tx=pre.x+dx[i]; 40 int ty=pre.y+dy[i]; 41 if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty]!='#'&&!vis[tx][ty]){ 42 vis[tx][ty]=true; 43 now.x=tx; 44 now.y=ty; 45 now.id=pre.id; 46 now.step=pre.step+1; 47 q.push(now); 48 } 49 } 50 } 51 } 52 class Prim { ///最小生成树(无向图)o(MV^2)要保证图连通 53 typedef int typec;///边权的类型 54 static const int MV=M;///点的个数 55 int n,i,j,k,pre[MV];///pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1 56 bool vis[MV]; 57 typec mat[MV][MV],dist[MV],res; 58 public: 59 void init(int tn) { ///传入点数,点下标0开始 60 n=tn; 61 for(i=0; i<n; i++) 62 for(j=0; j<n; j++) 63 mat[i][j]=i==j?0:inf;///不相邻点边权inf 64 } 65 void add(int u,int v,typec w) { 66 if(mat[u][v]>w) { 67 mat[u][v]=w; 68 mat[v][u]=w; 69 } 70 } 71 typec solve() { ///返回最小生成树的长度 72 for(res=i=0; i<n; i++) { 73 dist[i]=inf; 74 vis[i]=false; 75 pre[i]=-1; 76 } 77 for(dist[j=0]=0; j<n; j++) { 78 for(k=-1,i=0; i<n; i++) { 79 if(!vis[i]&&(k==-1||dist[i]<dist[k])) { 80 k=i; 81 } 82 } 83 for(vis[k]=true,res+=dist[k],i=0; i<n; i++) { 84 if(!vis[i]&&mat[k][i]<dist[i]) { 85 dist[i]=mat[pre[i]=k][i]; 86 } 87 } 88 } 89 return res; 90 } 91 }gx; 92 int main(){ 93 int t; 94 while(~scanf("%d",&t)){ 95 while(t--){ 96 scanf("%d%d",&m,&n); 97 while(getchar()==' ') getchar(); 98 for(int i=0;i<n;i++){ 99 gets(a[i]); 100 } 101 int lp=0; 102 for(int i=0;i<n;i++){ 103 for(int j=0;j<m;j++){ 104 if(ispoint(a[i][j])){ 105 num[i][j]=lp; 106 p[lp].x=i; 107 p[lp].y=j; 108 lp++; 109 } 110 else{ 111 num[i][j]=-1; 112 } 113 } 114 } 115 for(int i=0;i<lp;i++){ 116 for(int j=0;j<lp;j++){ 117 cost[i][j]=inf; 118 } 119 cost[i][i]=0; 120 } 121 for(int i=0;i<lp;i++){ 122 now.x=p[i].x; 123 now.y=p[i].y; 124 now.id=i; 125 now.step=0; 126 bfs(now); 127 } 128 gx.init(lp); 129 for(int i=0;i<lp;i++){ 130 for(int j=0;j<lp;j++){ 131 gx.add(i,j,cost[i][j]); 132 } 133 } 134 printf("%d\n",gx.solve()); 135 } 136 } 137 return 0; 138 }
kruskal
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<algorithm> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int inf=0x3f3f3f3f; 8 const int M=2024; 9 int n,m; 10 struct P{ 11 int x,y; 12 }p[M*M]; 13 char a[M][M]; 14 int num[M][M]; 15 int cost[M][M]; 16 bool ispoint(char c){ 17 if(c=='S'||c=='A') return true;return false; 18 } 19 struct Q{ 20 int x,y,id,step; 21 }pre,now; 22 queue<Q> q; 23 int dx[]={0,0,1,-1}; 24 int dy[]={1,-1,0,0}; 25 bool vis[M][M]; 26 void bfs(Q now){ 27 mt(vis,0); 28 while(!q.empty()) q.pop(); 29 q.push(now); 30 vis[now.x][now.y]=true; 31 while(!q.empty()){ 32 pre=q.front(); 33 q.pop(); 34 if(ispoint(a[pre.x][pre.y])){ 35 if(cost[pre.id][num[pre.x][pre.y]]>pre.step) 36 cost[pre.id][num[pre.x][pre.y]]=pre.step; 37 } 38 for(int i=0;i<4;i++){ 39 int tx=pre.x+dx[i]; 40 int ty=pre.y+dy[i]; 41 if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty]!='#'&&!vis[tx][ty]){ 42 vis[tx][ty]=true; 43 now.x=tx; 44 now.y=ty; 45 now.id=pre.id; 46 now.step=pre.step+1; 47 q.push(now); 48 } 49 } 50 } 51 } 52 class Kruskal { ///最小生成树(无向图)o(ME*logME) 53 typedef int typec;///边权的类型 54 static const int ME=M*M;///边的个数 55 static const int MV=M;///点的个数 56 class UnionFindSet { ///并查集 57 int par[MV]; 58 public: 59 void init() { 60 mt(par,-1); 61 } 62 int getroot(int x) { 63 int i=x,j=x,temp; 64 while(par[i]>=0) i=par[i]; 65 while(j!=i) { 66 temp=par[j]; 67 par[j]=i; 68 j=temp; 69 } 70 return i; 71 } 72 bool unite(int x,int y) { 73 int p=getroot(x); 74 int q=getroot(y); 75 if(p==q)return false; 76 if(par[p]>par[q]) { 77 par[q]+=par[p]; 78 par[p]=q; 79 } else { 80 par[p]+=par[q]; 81 par[q]=p; 82 } 83 return true; 84 } 85 } f; 86 struct E { 87 int u,v; 88 typec w; 89 friend bool operator < (E a,E b) { 90 return a.w<b.w; 91 } 92 } e[ME]; 93 int le,num,n; 94 typec res; 95 public: 96 void init(int tn){///传入点的个数 97 n=tn; 98 le=res=0; 99 f.init(); 100 num=1; 101 } 102 void add(int u,int v,typec w) { 103 e[le].u=u; 104 e[le].v=v; 105 e[le].w=w; 106 le++; 107 } 108 typec solve(){///返回-1不连通 109 sort(e,e+le); 110 for(int i=0; i<le&&num<n; i++) { 111 if(f.unite(e[i].u,e[i].v)) { 112 num++; 113 res+=e[i].w; 114 } 115 } 116 if(num<n) res=-1; 117 return res; 118 } 119 }gx; 120 int main(){ 121 int t; 122 while(~scanf("%d",&t)){ 123 while(t--){ 124 scanf("%d%d",&m,&n); 125 while(getchar()==' ') getchar(); 126 for(int i=0;i<n;i++){ 127 gets(a[i]); 128 } 129 int lp=0; 130 for(int i=0;i<n;i++){ 131 for(int j=0;j<m;j++){ 132 if(ispoint(a[i][j])){ 133 num[i][j]=lp; 134 p[lp].x=i; 135 p[lp].y=j; 136 lp++; 137 } 138 else{ 139 num[i][j]=-1; 140 } 141 } 142 } 143 for(int i=0;i<lp;i++){ 144 for(int j=0;j<lp;j++){ 145 cost[i][j]=inf; 146 } 147 cost[i][i]=0; 148 } 149 for(int i=0;i<lp;i++){ 150 now.x=p[i].x; 151 now.y=p[i].y; 152 now.id=i; 153 now.step=0; 154 bfs(now); 155 } 156 gx.init(lp); 157 for(int i=0;i<lp;i++){ 158 for(int j=i+1;j<lp;j++){ 159 gx.add(i,j,cost[i][j]); 160 } 161 } 162 printf("%d\n",gx.solve()); 163 } 164 } 165 return 0; 166 }
end