最小生成树算法

1.wormhole

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<stack>
 5 #include<cstring>
 6 #include<algorithm>
 7 
 8 using namespace std;
 9 #define INF 99999999
10 #define N 501
11 int g[N][N];
12 int d[N];
13 int n,m,w;
14 
15 bool BELLMAN_FORD()
16 {
17     for (int i=0;i<n;i++)
18         d[i]=INF;
19     d[0]=0;
20     for (int k=0;k<n-1;k++)
21         for (int i=0;i<n;i++)
22             for (int j=0;j<n;j++)
23                 if ((g[i][j]!=INF)&&(d[j]>d[i]+g[i][j]))
24                     d[j]=d[i]+g[i][j];
25     for (int i=0;i<n;i++)
26         for (int j=0;j<n;j++)
27             if ((g[i][j]!=INF)&&(d[j]>d[i]+g[i][j])) return false;
28     return true;
29 }
30 int main()
31 {
32     int _count;
33     scanf("%d",&_count);
34     for (int q=0;q<_count;q++)
35     {
36         scanf("%d%d%d",&n,&m,&w);
37         for (int i=0;i<n;i++)
38             for (int j=0;j<n;j++)
39                 g[i][j]=INF;
40         int u,v,t;
41         for (int i=0;i<m;i++)
42         {
43             scanf("%d%d%d",&u,&v,&t);
44             if (g[u-1][v-1]>t) g[u-1][v-1]=t;
45             if (g[v-1][u-1]>t) g[v-1][u-1]=t;
46         }
47         for (int i=0;i<w;i++)
48         {
49             scanf("%d%d%d",&u,&v,&t);
50             g[u-1][v-1]=-t;
51         }
52         if (BELLMAN_FORD()) printf("NO
");
53         else printf("YES
");
54     }
55     return 0;
56 }
View Code

 2.Truck History

 1 #include<iostream>
 2 #include<cstdio>
 3 
 4 using namespace std;
 5 
 6 #define N 2005
 7 #define INF 99999999
 8 
 9 int g[N][N];
10 char s[N][7];
11 int n,count,result;
12 int inq[N];
13 
14 void prim()
15 {
16     result=0;
17     int u,v,w;
18     /*for (int i=0;i<n;i++) inq[i]=0;
19     inq[0]=1;
20     count=n-1;
21     while (count--){
22         w=INF;
23         for (int i=0;i<n;i++)
24         {
25             if (inq[i]==1)
26                 for (int j=0;j<n;j++)
27                     if ((inq[j]==0)&&(g[i][j]<w))
28                     {
29                         v=j;
30                         w=g[i][j];
31                     }
32         }
33         inq[v]=1;
34         result+=w;
35     }*/
36 //关于如何优化朴素prim:如果想用邻接矩阵加数组,则上面的算法在每一次循环时要对队列里所有点的邻接边求最小值,会产生大量重复计算,只需要在每次加入节点时求其邻接边的最小值再判断是否替换即可
37     for (int i=1;i<n;i++) inq[i]=g[0][i];
38     inq[0]=0;
39     for (int i=1;i<n;i++)
40     {
41         int min = INF;
42         v = 0;
43         for (int j=1;j<n;j++)
44             if ((inq[j]<min)&&(inq[j]!=0))
45             {
46                 min=inq[j];
47                 v=j;
48             }
49         result+=min;
50         inq[v]=0;
51         for (int j=1;j<n;j++)
52             if (g[v][j]<inq[j]) inq[j]=g[v][j];
53     }
54 
55 }    
56 
57 
58 int main()
59 {
60     while (scanf("%d",&n)&&n)
61     {
62         for (int i=0;i<n;i++)
63             for (int j=0;j<n;j++)
64                 g[i][j]=INF;
65         for (int i=0;i<n;i++)
66         {
67             scanf("%s",&s[i]);
68             for (int j=0;j<i;j++)
69             {
70                 count=0;
71                 for (int k=0;k<7;k++)
72                     if (s[j][k]!=s[i][k]) count++;
73                 g[i][j]=g[j][i]=count;
74             }
75         }
76         prim();
77         printf("The highest possible quality is 1/%d.
",result);
78     }
79     return 0;
80 }
View Code

 3.POJ 3723 Conscription

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 
 6 using namespace std;
 7 
 8 #define N 10005
 9 #define E 50005
10 #define INF 99999999
11 
12 struct Edge{
13     int u,v;
14     int w;
15     //friend bool operator< (Edge e1,Edge e2)
16     //    return e1.w > e2.w;
17 }edge[E];
18 int n,m,r,result;
19 int pi[2*N];
20 bool _cmp(Edge e1,Edge e2)
21 {
22     return e1.w > e2.w;
23 }
24 
25 void MAKE_SET()
26 {
27     for (int i=0;i<(m+n);i++)
28         pi[i]=i;
29 }
30 
31 int FIND(int u)
32 {
33     if (pi[u]==u) return u;
34     else return (FIND(pi[u]));
35 }
36 
37 void UNION(int u,int v)
38 {
39     int _min = pi[u]>pi[v]?pi[v]:pi[u];
40     pi[u]=pi[v]=_min;
41 }
42 
43 
44 void kruskal()
45 {
46     sort(edge,edge+r,_cmp);
47     MAKE_SET();
48     for (int i=0;i<r;i++)
49     {
50         int u=edge[i].u,v=edge[i].v,w=edge[i].w;
51 /**************/
52         u=FIND(u);
53         v=FIND(v);
54         if (u!=v)
55 /**************/
56 //if (FIND(u)!=FIND(v))
57 //注意:UNION不只是对点的操作,是要合并两棵树
58 //如果按注释掉的方法写,则下面应该UNION(FIND(u),FIND(v));
59         {
60             UNION(u,v);
61             result-=w;
62         }
63     }
64 }
65 
66 int main()
67 {
68     int count;
69     scanf("%d",&count);
70     while (count--)
71     {
72         scanf("%d%d%d",&n,&m,&r);
73         for (int i=0;i<r;i++)
74         {
75             int v;
76             scanf("%d%d%d",&edge[i].u,&v,&edge[i].w);
77             edge[i].v=v+n;
78         }
79         result = 10000*(n+m);
80         kruskal();
81         printf("%d
",result);
82     }
83     return 0;
84 }
View Code

 4.POJ 2031 Building a space station

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 
 7 using namespace std;
 8 
 9 #define N 2000
10 #define INF 99999999.0
11 struct Node{
12     double x,y,z,r;
13 }node[N];
14 double g[N][N],result,low[N],vis[N];
15 int n;
16 
17 void prim()
18 {
19     for (int i=1;i<n;i++)
20         low[i]=g[0][i];
21     low[0]=-1;
22     for (int i=1;i<n;i++)
23     {
24         double min=INF;
25         int v=0;
26         for (int j=1;j<n;j++)
27         {
28             if ((low[j]<min)&&(low[j]!=-1))
29             {
30                 min=low[j];
31                 v=j;
32             }
33         }
34         result+=min;
35         low[v]=-1;
36         for (int j=1;j<n;j++)
37             if (g[v][j]<low[j]) low[j]=g[v][j];
38     }
39 }
40 int main()
41 {
42     while (scanf("%d",&n)&&n)
43     {
44         for (int i=0;i<n;i++)
45         {
46             low[i]=INF;
47             for (int j=0;j<n;j++)
48                 g[i][j]=INF;
49         }
50         double x1,y1,z1,r1,x2,y2,z2,r2;
51         for (int i=0;i<n;i++)
52             scanf("%lf%lf%lf%lf",&node[i].x,&node[i].y,&node[i].z,&node[i].r);
53         for (int i=0;i<n;i++)
54             for (int j=0;j<n;j++)
55             {
56                 x1=node[i].x;
57                 x2=node[j].x;
58                 y1=node[i].y;
59                 y2=node[j].y;
60                 z1=node[i].z;
61                 z2=node[j].z;
62                 r1=node[i].r;
63                 r2=node[j].r;
64                 double temp = sqrt(pow(x1-x2,2)+pow(y1-y2,2)+pow(z1-z2,2))-(r1+r2);
65                 if (temp > pow(10.0,-6)) g[i][j]=g[j][i]=temp;
66                 else g[i][j]=g[j][i]=0;
67             }
68         result = 0;
69         prim();
70         printf("%.3lf
",result);
71     }
72     return 0;
73 }
View Code
原文地址:https://www.cnblogs.com/giddens/p/4489239.html