Hdu-1102 Constructing Roads

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102


题目大意:

N个村庄修路,给你他们之间的花费,然后还有一部分村庄已经修好路,求最小花费。


思路:

赤裸裸的最小生成树算法


prime算法代码如下:

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int map[110][110], lowcost[110]; bool visit[110]; int sum, num; void prime() { int temp, k; visit[1] = 1; for(int i = 2; i <= num; ++i) lowcost[i] = map[1][i]; for(int i = 2; i <= num; ++i) { temp = 0x0fffffff; for(int j = 2; j <= num; ++j) { if(!visit[j] && lowcost[j] < temp) { temp = lowcost[j]; k = j; } } sum += temp; visit[k] = 1; for(int j = 2; j <= num; ++j) if(!visit[j] && lowcost[j] > map[k][j]) lowcost[j] = map[k][j]; } } int main() { int x, y, cost, already , x1, y1; while(scanf("%d", &num) != EOF) { memset(map, 0, sizeof(map)); memset(lowcost, 0, sizeof(lowcost)); memset(visit, 0, sizeof(visit)); sum = 0; for(int i = 1; i <= num; ++i) for(int j = 1; j <= num; ++j) scanf("%d", &map[i][j]); scanf("%d", &already); for(int i = 0; i < already; ++i) { scanf("%d%d", &x1, &y1); map[x1][y1] = map[y1][x1] = 0; } prime(); printf("%d\n", sum); } return 0; }
Kurskal算法代码如下:

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int pre[110], map[110][110]; struct Kruskal { int a, b, cost; }; Kruskal village[110 * 110 / 2]; bool cmp(const Kruskal &a, const Kruskal &b) { return a.cost < b.cost; } int unionsearch(int x) //查找根结点 { return x == pre[x] ? x : unionsearch(pre[x]); } bool join(int x, int y) { int root1, root2; root1 = unionsearch(x); root2 = unionsearch(y); if(root1 == root2) return false; pre[root1] = root2; return true; } int main() { int num, k, already, a, b, x, y, sum; while(scanf("%d", &num) != EOF) { memset(pre, 0, sizeof(pre)); memset(map, 0, sizeof(map)); for(int i = 1; i <= num; ++i) pre[i] = i; for(int i = 1; i <= num; ++i) for(int j = 1; j <= num; ++j) scanf("%d", &map[i][j]); k = 0; for(int i = 1; i <= num; ++i) for(int j = i + 1; j <= num; ++j) { village[k].a = i; village[k].b = j; village[k].cost = map[i][j]; k++; } sort(village, village + k, cmp); scanf("%d", &already); for(int i = 1; i <= already; ++i) { scanf("%d%d", &a, &b); x = unionsearch(a); y = unionsearch(b); if(x != y) pre[y] = x; } sum = 0; for(int i = 0; i < k; ++i) if(join(village[i].a, village[i].b)) sum += village[i].cost; printf("%d\n", sum); } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值