http://acm.hdu.edu.cn/showproblem.php?pid=1879 继续畅通工程
寻找最小生成树,可以使用prim算法,亦可以使用kruskal算法。以下使用prim算法实现。
- //继续畅通工程 prim算法
- #include<stdio.h>
- #define N 105
- int matrix[N][N];
- int flag[N];
- int length[N];
- int d[N];
- int get_min(int n)
- {
- int min;
- int i;
- for (i = 1; i <= n; i++)
- {
- if (flag[i] == 0)
- {
- min = i;
- break;
- }
- }
- for (i++; i <= n; i++)
- {
- if (flag[i] == 0 && length[min] > length[i])
- min = i;
- }
- return min;
- }
- int prim(int n)
- {
- int i, j;
- int min;
- int sum;
- for (i = 1; i <= n; i++)
- {
- flag[i] = 0;
- length[i] = matrix[1][i];
- d[i] = 1;
- }
- flag[1] = 1;
- sum = 0;
- for (i = 2; i <= n; i++)
- {
- min = get_min(n);
- flag[min] = 1;
- sum += length[min];
- for (j = 1; j <= n; j++)
- {
- if (flag[j] == 0)
- {
- if (matrix[min][j] < length[j])
- {
- length[j] = matrix[min][j];
- d[j] = min;
- }
- }
- }
- }
- return sum;
- }
- void main()
- {
- int n, m;
- int i;
- int min;
- int u, v, cost, tag;
- // freopen("input.txt", "r", stdin);
- while (scanf("%d", &n) != EOF && n != 0)
- {
- m = n * (n - 1) / 2;
- for (i = 0; i <= n; i++)
- matrix[i][i] = 0;
- for (i = 0; i < m; i++)
- {
- scanf("%d%d%d%d", &u, &v, &cost, &tag);
- if (tag == 1)
- {
- matrix[u][v] = 0;
- matrix[v][u] = 0;
- }
- else
- {
- matrix[u][v] = cost;
- matrix[v][u] = cost;
- }
- }
- min = prim(n);
- printf("%d\n", min);
- }
- }
以下是Kruskal算法,先使用快速排序为两个城市的成本排序,再使用并查集判断增加某条边后是否构成环。
- //继续畅通工程 kruskal算法与使用并查集
- #include<stdio.h>
- #define N 105
- struct arc_node{
- int u, v;
- int cost;
- };
- struct arc_node edge[N * (N - 1) / 2];
- int parent[N];
- int height[N];
- int qsort(int low, int high)
- {
- struct arc_node t;
- int temp;
- int i, j;
- if (low < high)
- {
- temp = edge[high].cost;
- i = low;
- for (j = low; j < high; j++)
- {
- if (edge[j].cost < temp)
- {
- t = edge[j];
- edge[j] = edge[i];
- edge[i] = t;
- i++;
- }
- }
- t = edge[j];
- edge[j] = edge[i];
- edge[i] = t;
- qsort(low, i - 1);
- qsort(i + 1, high);
- }
- return 1;
- }
- int get_parent(int n)
- {
- while (parent[n] != n)
- n = parent[n];
- return n;
- }
- void main()
- {
- int n, m;
- int tag;
- int i;
- int sum, count;
- int temp1, temp2;
- // freopen("input.txt", "r", stdin);
- while (scanf("%d", &n) != EOF && n != 0)
- {
- m = n * (n - 1) / 2;
- for (i = 0; i < m; i++)
- {
- scanf("%d%d%d%d", &edge[i].u, &edge[i].v, &edge[i].cost, &tag);
- if (tag == 1)
- {
- edge[i].cost = 0;
- }
- }
- qsort(0, m - 1);
- for (i = 1; i <= n; i++)
- {
- parent[i] = i;
- height[i] = 1;
- }
- count = 0;
- sum = 0;
- for (i = 0; i < m; i++)
- {
- temp1 = get_parent(edge[i].u);
- temp2 = get_parent(edge[i].v);
- if (temp1 != temp2)
- {
- count++;
- sum += edge[i].cost;
- if (height[temp1] == height[temp2])
- {
- height[temp1]++;
- parent[temp2] = temp1;
- }
- else
- {
- if (height[temp1] > height[temp2])
- parent[temp2] = temp1;
- else
- parent[temp1] = temp2;
- }
- if (count == n - 1)
- break;
- }
- }
- printf("%d\n", sum);
- }
- }
转载于:https://blog.51cto.com/2853126/640961