题意:要在n个城市之间建造公路,使城市之间能互相联通,告诉每个城市之间建公路的费用,和已经建好的公路,求最小费用。
解法:最小生成树。先把已经建好的边加进去再跑kruskal或者prim什么的。
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; struct node { int u, v, val; bool operator < (const node &tmp) const { return val < tmp.val; } }edge[10005]; int father[105]; int Find(int a) { if(a != father[a]) father[a] = Find(father[a]); return father[a]; } bool Union(int a, int b) { int c = Find(a), d = Find(b); if(c == d) return false; father[c] = d; return true; } int main() { int n; while(~scanf("%d", &n)) { int cnt = 0; for(int i = 1; i <= n; i++) father[i] = i; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { int x; scanf("%d", &x); if(i <= j) continue; edge[cnt].u = i; edge[cnt].v = j; edge[cnt++].val = x; } } int m; scanf("%d", &m); for(int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); Union(a, b); } sort(edge, edge + cnt); int ans = 0; for(int i = 0; i < cnt; i++) { if(Union(edge[i].u, edge[i].v)) ans += edge[i].val; } printf("%d ", ans); } return 0; }