最小生成树

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 }
View Code

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 }
View Code

 

 

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 }
View Code

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 }
View Code

 

 

 

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 }
View Code

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 }
View Code

 

 

 

 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 }
View Code

 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 }
View Code

 

 

 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 }
View Code

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 }
View Code

 

 

 

 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 }
View Code

 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 }
View Code

 

 

end

posted on 2014-08-29 10:17  gaolzzxin  阅读(237)  评论(0编辑  收藏  举报