(图论)51NOD 1212 无向图最小生成树

N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。

输入

第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)

输出

输出最小生成树的所有边的权值之和。

输入样例

9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8

输出样例

37
解:Kruskal算法(排序后添加边)的两种实现(时间消耗差不多):
 1 #include 
 2 #include 
 3 #include <string.h>
 4 
 5 typedef struct Graph
 6 {
 7     int s,e,w;
 8 }graph;
 9 
10 int cmp(const void *a,const void *b)
11 {
12     return (*(graph *)a).w>(*(graph *)b).w?1:-1;
13 }
14 
15 graph p[50005];
16 int vis[1005];
17 
18 int main()
19 {
20    int n,m;
21    while(scanf_s("%d%d",&n,&m)!=EOF)
22    {
23         int i,j,ans=0;
24         memset(vis,0,n);
25         for(i=0;i"%d%d%d",&p[i].s,&p[i].e,&p[i].w);
26         qsort(p,m,sizeof(graph),cmp);
27         vis[p[0].s]=1;
28         vis[p[0].e]=1;
29         ans+=p[0].w;
30         for(i=0;i2;i++)
31         {
32             for(j=0;j)
33             {
34                 if((vis[p[j].s]==0&&vis[p[j].e]==0)||(vis[p[j].s]&&vis[p[j].e]))
35                     continue;
36                 else
37                 {
38                     vis[p[j].s]=1;
39                     vis[p[j].e]=1;
40                     ans+=p[j].w;
41                     break;
42                 }
43             }
44         }
45         printf("%d\n",ans);
46    }
47    return 0;
48 }

 

 1 #include
 2 #include
 3 #include<malloc.h>
 4 
 5 typedef struct GRAPH
 6 {
 7     int s, e, w;
 8 }graph;
 9 
10 
11 int cmp(const void *a, const void *b)
12 {
13     return ((graph *)a)->w > ((graph *)b)->w ? 1 : -1;
14 }
15     
16 graph p[50005];
17 int *vis[1005];
18 
19 int main()
20 {
21     int n, m;
22     while (scanf_s("%d%d", &n, &m) != EOF)
23     {
24         int ans = 0;
25         for (int i = 0; i < m; ++i) scanf_s("%d%d%d", &p[i].s, &p[i].e, &p[i].w);
26         qsort(p, m, sizeof(graph), cmp);
27         for (int i = 0, j = 0; i < m; ++i)
28         {
29             int *tmp = (int *)malloc(sizeof(int));
30             if (vis[p[i].e] == NULL)
31             {
32                 if (vis[p[i].s] == NULL)
33                 {
34                     *tmp = j++;
35                     vis[p[i].e] = vis[p[i].s] = tmp;
36                 }
37                 else
38                 {
39                     vis[p[i].e] = vis[p[i].s];
40                     free(tmp);
41                 }
42             }
43             else if (vis[p[i].s] == NULL)
44             {
45                 vis[p[i].s] = vis[p[i].e];
46                 free(tmp);
47             }
48             else
49             {
50                 int *a, *b;
51                 for (a = vis[p[i].s]; *a > 505; a = *a);
52                 for (b = vis[p[i].e]; *b > 505; b = *b);
53                 if (*a == *b)
54                 {
55                     free(tmp);
56                     continue;
57                 }
58                 else
59                 {
60                     *tmp = *a;
61                     *b = *a = tmp;
62                 }
63             }
64             ans += p[i].w;
65         }
66         printf("%d\n", ans);
67     }
68 }

 Prim算法(排序后添加点)(写的不好,时间消耗比上面的长):

 1 #include 
 2 #include <malloc.h>
 3 #include <string.h>
 4 
 5 #define MIN(a,b) (pt[a]->prpr?a:b)
 6 
 7 typedef struct POINT
 8 {
 9     struct POINT *p;
10     int ed,pr;
11 }point;
12 
13 point *pt[1005];
14 int vis[2][1005];
15 int main()
16 {
17     int n, m;
18     while (scanf_s("%d%d", &n, &m) != EOF)
19     {
20         int ans = 0;
21         while (m--)
22         {
23             int a, b, c;
24             scanf_s("%d%d%d", &a, &b, &c);
25             point *tmp1 = (point *)malloc(sizeof(point)), *tmp2 = (point *)malloc(sizeof(point));
26             tmp1->ed = b;
27             tmp2->ed = a;
28             tmp1->pr = tmp2->pr = c;
29             if (pt[a] == NULL|| tmp1->pr < pt[a]->pr)
30             {
31                 tmp1->p = pt[a];
32                 pt[a] = tmp1;            
33             }
34             else for (point *tmp0 = pt[a], *tmp = pt[a]; tmp0 != NULL; tmp = tmp->p)
35             {
36                 if (tmp == NULL||tmp1->pr < tmp->pr)
37                 {
38                     tmp1->p = tmp0->p;
39                     tmp0->p = tmp1;
40                     break;
41                 }
42                 tmp0 = tmp;
43             }
44             if (pt[b] == NULL || tmp2->pr < pt[b]->pr)
45             {
46                 tmp2->p = pt[b];
47                 pt[b] = tmp2;
48             }
49             else for (point *tmp0 = pt[a], *tmp = pt[b]; tmp0 != NULL; tmp = tmp->p)
50             {
51                 if (tmp == NULL || tmp2->pr < tmp->pr)
52                 {
53                     tmp2->p = tmp0->p;
54                     tmp0->p = tmp2;
55                     break;
56                 }
57                 tmp0 = tmp;
58             }
59         }
60         vis[0][1] = 1;
61         vis[1][1] = 1;
62         for (int i = 1; i < n; i++)
63         {
64             int tmp = 0;
65             for (int j = 1; j <= i; j++)
66             {
67                 if (pt[vis[0][j]] == NULL) continue;
68                 else if(vis[1][pt[vis[0][j]]->ed]!=1)
69                 {
70                     if (0 == tmp) tmp = vis[0][j];
71                     else tmp = MIN(tmp, vis[0][j]);
72                 }
73                 else
74                 {
75                     pt[vis[0][j]] = pt[vis[0][j]]->p;
76                     j--;
77                 }
78             }
79             vis[0][i+1] = pt[tmp]->ed;
80             vis[1][pt[tmp]->ed] = 1;
81             ans += pt[tmp]->pr;
82             pt[tmp] = pt[tmp]->p;
83         }
84         printf("%d\n", ans);
85     }
86 }

 

转载于:https://www.cnblogs.com/Ekalos-blog/p/9932581.html

你可能感兴趣的:((图论)51NOD 1212 无向图最小生成树)