hdu1102 最小生成树
本题本是模板题,但由于开始并查集写出,好不容易发现了,有没改彻底,导致狂WA,以后一定要注意,修改后要多检查,别急忙交;
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #define maxn 105 using namespace std; const int INF = 0x3f3f3f; int G[maxn][maxn]; struct Edge{ int from; int to; int len; bool operator <(const Edge& rh) const { return len < rh.len ; } }; struct MST{ int n; int m; Edge edge[maxn*maxn]; int p[maxn]; void init(int num){ m = 0; n = num; for(int i=0;i<n;i++) p[i] = i; } int find(int x){ return p[x]==x ? x : p[x] = find(p[x]); } void Addedge(int i,int j,int len){ edge[m].from = i; edge[m].to = j; edge[m].len = len; m++; } int krusal(){ int ans = 0; sort(edge,edge+m); for(int i=0;i<m;i++){ int x = edge[i].from; int y = edge[i].to;; int z = edge[i].len; if(find(x) != find(y)){ int a = find(x),b = find(y); //这是刚开始 WA 的原因; p[a] = b; ans += z; } } return ans; } }Slover; int main(){ //if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);} int N; while(cin>>N){ memset(G,0,sizeof(G)); Slover.init(N); for(int i=0;i<N;i++) for(int j=0;j<N;j++){ cin>>G[i][j]; } for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){ Slover.Addedge(i,j,G[i][j]); } int Q; cin>>Q; for(int i=0;i<Q;i++){ int a,b; cin>>a>>b; a--; b--; if(Slover.find(a) != Slover.find(b)){ int x = Slover.find(a),y = Slover.find(b); Slover.p[x] = y; //这么改到位 } } int ans = Slover.krusal(); printf("%d\n",ans); } return 0; }
prim算法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #define maxn 105 using namespace std; const int INF = 0x3f3f3f; int G[maxn][maxn]; int ans; int n; void prim(){ bool vis[maxn]; int lowdist[maxn]; //每个点的最小相邻边; int mindist; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) lowdist[i]=INF; int point; int s=1; vis[s] =true; int num=1; while(true){ if(num == n) break; vis[s]=true; mindist = INF; for(int i=1;i<=n;i++){ if(!vis[i] && lowdist[i] > G[s][i]){ lowdist[i] = G[s][i]; } if(!vis[i] && mindist>lowdist[i]){ mindist=lowdist[i]; point = i; //printf("%d %d %d\n",G[1][2],mindist,i); } } s = point; ans += mindist; num++; } return; } int main(){ //if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);} while(cin>>n){ memset(G,0x3f,sizeof(G)); ans = 0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ cin>>G[i][j]; } int Q; cin>>Q; for(int i=0;i<Q;i++){ int a,b; cin>>a>>b; G[a][b] = G[b][a] = 0; } //print(); prim(); printf("%d\n",ans); } return 0; }