题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232
并查集水。
#include<bits/stdc++.h> using namespace std; const int N=1005; int n,m; int father[N]; int find(int x){ if(x==father[x]) return x; return find(father[x]); } int main(){ while(scanf("%d",&n)&(n!=0)){ for(int i=1;i<=n;i++) father[i]=i; scanf("%d",&m); for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); int x=find(a),y=find(b); if(x!=y) father[x]=y; } int ans=0; for(int i=1;i<=n;i++){ if(father[i]==i) ans++; } printf("%d\n",ans-1); } }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233
解法一 kruskal
#include<bits/stdc++.h> using namespace std; const int N=105; struct node{ int x,y,z; }a[(N*N)/2]; int n,m,father[N]; bool cmp(node a,node b){ return a.z<b.z; } int find(int x){ if(x==father[x]) return x; return find(father[x]); } int main(){ while(scanf("%d",&n)&(n!=0)){ for(int i=1;i<=n;i++) father[i]=i; m=n*(n-1)/2; for(int i=0;i<m;i++){ scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); } sort(a,a+m,cmp); int cost=0,cnt=0; for(int i=0;i<m;i++){ int a1=find(a[i].x),b1=find(a[i].y); if(a1!=b1){ father[a1]=b1; cost+=a[i].z; //cnt++; } //if(cnt==n-1) break; } printf("%d\n",cost); } }
解法二 prim算法
#include<bits/stdc++.h> using namespace std; const int N=105; const int INF=1e5+5; int lowcost[N],Map[N][N],n,m; bool vis[N]; int prim(){ int min,mincost=0,next; memset(vis,0,sizeof(vis)); for(int i=2;i<=n;i++) lowcost[i]=Map[1][i]; vis[1]=1; for(int i=2;i<=n;i++){ min=INF; for(int j=1;j<=n;j++){ if(min>lowcost[j]&&!vis[j]){ min=lowcost[j],next=j; } } mincost+=min; vis[next]=1; for(int k=1;k<=n;k++){ if(!vis[k]&&lowcost[k]>Map[next][k]) lowcost[k]=Map[next][k];//更新lowcost数组 } } return mincost; } int main(){ while(~scanf("%d",&n)&&n){ memset(Map,INF,sizeof(INF)); int a,b,c; m=(n-1)*n/2; while(m--){ scanf("%d%d%d",&a,&b,&c); Map[a][b]=Map[b][a]=c; } int need=prim(); printf("%d\n",need); } }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863
解法一 kruskal
#include<bits/stdc++.h> using namespace std; const int N=105; struct node{ int x,y,z; }a[N*(N-1)/2]; int n,m,pre[N]; int cmp(node a,node b){ return a.z<b.z; } void init(){ for(int i=1;i<=n;i++) pre[i]=i; } int find(int x){ if(x==pre[x]) return x; return find(pre[x]); } int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); sort(a+1,a+m+1,cmp); init(); int cost=0,cnt=0; for(int i=1;i<=m;i++){ int t1=find(a[i].x); int t2=find(a[i].y); if(t1!=t2){ pre[t1]=t2; cnt++; cost+=a[i].z; } //if(cnt==n-1) break; } if(cnt==n-1) printf("%d\n",cost); else printf("?\n"); } }
解法2 prim
memset一般只赋值为0和1
#include<bits/stdc++.h> using namespace std; const int INF=1e7+5; int lowcost[110],visit[110],map1[110][110]; int city,road,need, x,y,c; void prime() { int i,j; int next,min,mincost=0; memset(visit,0,sizeof(visit)); for(i=1;i<=city;i++) { lowcost[i]=map1[1][i]; } visit[1]=1; for(i=1;i<city;i++) { min=INF,next=0; for(j=1;j<=city;j++) { if(!visit[j]&&min>lowcost[j]) { min=lowcost[j]; next=j; } } if(!next){ printf("?\n"); return; } mincost+=min; visit[next]=1; for(j=1;j<=city;j++) { if(!visit[j]&&lowcost[j]>map1[next][j]) { lowcost[j]=map1[next][j]; } } } printf("%d\n",mincost); } int main() { while(~scanf("%d%d",&city,&road)) { for(int i=1;i<=city;i++) for(int j=1;j<=city;j++) map1[i][j]=INF; while(road--) { scanf("%d%d%d",&x,&y,&c); map1[x][y]=map1[y][x]=c; } prime(); } return 0; }
题目链接:http://www.pipioj.online/problem.php?id=1118
简单处理一下就好了,注意不要忘了初始化
#include<bits/stdc++.h> using namespace std; const int N=100; struct node{ int x,y,z,w; }a[(N-1)*N/2]; int father[N],n,m; int find(int x){ if(x==father[x]) return x; return find(father[x]); } bool cmp(node a,node b){ return a.z<b.z; } int main(){ while(scanf("%d",&n)&&(n)){ m=(n-1)*n/2; for(int i=0;i<m;i++){ scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].w); if(a[i].w==1) a[i].z=0; } for(int i=1;i<=n;i++) father[i]=i;//初始化 sort(a,a+m,cmp); int ans=0; for(int i=0;i<m;i++){ int t1=find(a[i].x); int t2=find(a[i].y); if(t1!=t2){ father[t1]=t2; ans+=a[i].z; } } printf("%d\n",ans); } }