题目链接:怒点
开始学习最小生成树的Kruscal算法了,还行,和prim是有区别的。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Max=5000;
struct X
{
int x,y;
int q;
}l[Max];
bool cmp(X x,X y)
{
if(x.q<y.q) return true;
return false;
}
int Kruscal(int n,bool vis[],int Yet,int nodeset[],int t)
{
int m=Yet,first=0,min=0;
sort(l,l+t,cmp);
while(m<(n-1))
{
if(!vis[l[first].x]&&vis[l[first].y])
{
min+=l[first].q;
vis[l[first].x]=true;
nodeset[l[first].x]=nodeset[l[first].y];
m++;
}
else if(vis[l[first].x]&&!vis[l[first].y])
{
min+=l[first].q;
vis[l[first].y]=true;
nodeset[l[first].y]=nodeset[l[first].x];
m++;
}
else if(!vis[l[first].x]&&!vis[l[first].y])
{
min+=l[first].q;
vis[l[first].y]=true;
vis[l[first].x]=true;
nodeset[l[first].y]=nodeset[l[first].x];
m++;
}
else
{
if(nodeset[l[first].x]!=nodeset[l[first].y])
{
min+=l[first].q;
int temp=nodeset[l[first].x];
for(int j=1;j<=n;j++)
if(temp==nodeset[j])
nodeset[j]=nodeset[l[first].y];
m++;
}
}
first++;
}
return min;
}
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
bool vis[105];
memset(vis,false,sizeof(vis));
int a,b,c,mark,Yet=0,nodeset[105],first=0;
for(int i=0;i<=n;i++)
nodeset[i]=i;
for(int i=1;i<=n*(n-1)/2;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&mark);
if(!mark)
{
l[first].x=a;
l[first].y=b;
l[first].q=c;
first++;
}
else
{
if(!vis[a]&&vis[b])
{
nodeset[a]=nodeset[b];
vis[a]=true;
}
else if(vis[a]&&!vis[b])
{
nodeset[b]=nodeset[a];
vis[b]=true;
}
else if(!vis[a]&&!vis[b])
{
nodeset[a]=nodeset[b];
vis[a]=true;
vis[b]=true;
}
else
{
if(nodeset[a]!=nodeset[b])
{
int temp=nodeset[a];
for(int k=1;k<=n;k++)
if(temp==nodeset[k])
nodeset[k]=nodeset[b];
}
}
Yet++;
}
}
printf("%d\n",Kruscal(n,vis,Yet,nodeset,first));
}
return 0;
}
冗余太多,以后要一步步的精简。
做出来这道题,让我刷了一版,重要的在已经连通的路上出现了一点问题。