Prim(点归并)
//异或运算:相同为假,不同为真 #include<cstdio> #include<algorithm> #define maxn 105 using namespace std; int n,m,sum,flag; int fa[maxn]; struct Edge { int u,v,w; bool operator<(const Edge &cmp)const{ return w<cmp.w; } }edge[maxn*maxn>>1]; int Findset(int x) { if(fa[x]==x) return fa[x]=x; else return fa[x]=Findset(fa[x]); } int main() { while(scanf("%d",&n),n){ m=(n-1)*n/2; for(int i=1;i<=n;i++) fa[i]=i; for(int i=0;i<m;i++){ scanf("%d%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w,&flag); if(flag) fa[edge[i].u]=edge[i].v; } sort(edge,edge+m); sum=0; for(int i=0;i<m;i++){ int x=Findset(edge[i].u); int y=Findset(edge[i].v); if(x!=y){ fa[x]=y; sum+=edge[i].w; } } printf("%d ",sum); } }
Kruscal(边归并)
#include<cstdio> #include<cstring> #define INF 0x3f3f3f3f #define maxn 105 int i,j,k,n,m,min,sum; int lowcost[maxn],visit[maxn]; int graph[maxn][maxn]; void Prim() { sum=0; memset(visit,0,sizeof(visit)); visit[1]=1; for(i=1;i<=n;i++) lowcost[i]=graph[1][i]; for(i=2;i<=n;i++){ min=INF; for(j=1;j<=n;j++){ if(!visit[j]&&min>lowcost[j]){ min=lowcost[j]; k=j; } } sum+=lowcost[k]; visit[k]=1; for(j=1;j<=n;j++){ if(!visit[j]&&lowcost[j]>graph[k][j]) lowcost[j]=graph[k][j]; } } } int main() { int a,b,c,d; while(scanf("%d",&n),n){ m=(n-1)*n/2; memset(graph,INF,sizeof(graph)); while(m--){ scanf("%d%d%d%d",&a,&b,&c,&d); if(d) graph[a][b]=graph[b][a]=0; else graph[a][b]=graph[b][a]=c; } Prim(); printf("%d ",sum); } return 0; }