最小生成树
对于必须要加入的边, 让其边权为0 即可
Prim :
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn = 100 + 31; const int INF=0x3f3f3f3f; int Map[maxn][maxn]; int Vis[maxn], Dis[maxn]; int ans; int n; void Prim() { int k; for(int i = 1; i <= n; ++i) Dis[i] = Map[1][i], Vis[i] = 0; Dis[1] = 0; Vis[1] = 1; for(int i = 1; i <= n; ++i) { int tmp = INF; for(int j = 1; j <= n; ++j) if(Vis[j] == 0 && tmp > Dis[j]) tmp = Dis[j], k = j; if(tmp == INF) break; Vis[k] = 1; ans += Dis[k]; for(int j = 1; j <= n; ++j) if(Vis[j] == 0 && Dis[j] > Map[k][j]) Dis[j] = Map[k][j]; } } int main() { while(~scanf("%d",&n)) { ans = 0; //memset(Map,INF,sizeof(Map)); for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) scanf("%d",&Map[i][j]); int q,a,b; scanf("%d",&q); while(q--) { scanf("%d%d",&a,&b); Map[a][b] = Map[b][a] = 0; } Prim(); printf("%d\n",ans); } return 0; }
\
Kruskal :
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> using namespace std; const int maxn = 100 + 7; struct Edges{ int u, v; int val; }edges[maxn * maxn]; int Pre[maxn]; int n,cnt,ans; void Add_Edge(int u,int v,int val) { edges[cnt].u = u, edges[cnt].v = v, edges[cnt].val = val; cnt ++; } void Init() { for(int i = 0; i < maxn ; ++i) Pre[i] = i; cnt = 0; ans = 0; } int Find(int x) { int r = x; while(r != Pre[r]) r = Pre[r]; return Pre[x] = r; } bool Union(int x,int y) { int ax = Find(x), ay = Find(y); if(ax == ay) return false; Pre[ax] = ay; return true; } bool cmp(Edges a, Edges b) { return a.val < b.val; } void Kruskal() { sort(edges,edges+cnt,cmp); for(int i = 0; i < cnt; ++i) { if(Union(edges[i].u,edges[i].v)) ans += edges[i].val; } } int main() { int n; while(~scanf("%d",&n)) { Init(); int a, b, q; for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) { scanf("%d",&a); Add_Edge(i,j,a); } scanf("%d",&q); while(q--) { scanf("%d%d",&a,&b); a = Find(a); b = Find(b); Pre[a] = b; } Kruskal(); printf("%d\n",ans); } return 0; }
第一道最小生成树,纪念一下。。