POJ 1258(最小生成树+知识)
用kruskal算法,利用w[i]给r[i]间接排序,从而r[i]可以按照边大小保存序号,同时要判断是否在一个集合里面
#include <cstdio> #include <iostream> #include <queue> using namespace std; #define sf scanf #define pf printf #define debug printf("!\n") #define blank printf("\n") #define mem(a,b) memset(a,b,sizeof(a)) const int MaxN = 110; const int INF = 1<<27; int p[MaxN]; int map[MaxN][MaxN],w[MaxN*MaxN],r[MaxN*MaxN],u[MaxN*MaxN],v[MaxN*MaxN]; int m,n; int find(int x){return p[x]==x?x:p[x]=find(p[x]);} int cmp(const int a,const int b) { return w[a]<w[b]; } int kruskal() { int ans = 0,i; for(i = 0;i<n;i++) p[i] = i; for(i = 0;i<m;i++) r[i] = i; sort(r,r+m,cmp); for(i = 0;i<m;i++) { int e = r[i]; int x = find(u[e]); int y = find(v[e]); if(x!=y) { ans+=w[e];p[x] = y; } } return ans; } int main() { int i,j; while(~sf("%d",&n)) { m = 0; mem(u,0); mem(v,0); mem(w,0); for(i = 0;i<n;i++) { for(j=0;j<n;j++) sf("%d",&map[i][j]); } for(i = 0;i<n;i++) { for(j=i+1;j<n;j++) { u[m] = i; v[m] = j; w[m++] = map[i][j]; } } int ans = kruskal(); pf("%d\n",ans); } return 0; }