这两天学习了最小生成树。学会了 prim算法和kruskal。我觉得kruskal比较简单,因为有用到我前面所学的并查集。
前面用prim写了第一题,感觉有点难,思路还好,就是不太会c++,里面的容器,函数不是很理解,当时生硬理解一下还是可以的。这次用kruskal写。
P3366 【模板】最小生成树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:最小生成树的枝干数比结点数少一,只需将两点之间的长度排序就可以了,降序排序,取前结点-1个长度,再加判断条件相加然后输出一下就可以了。
#include<bits/stdc++.h>
using namespace std;
struct st
{
int s;
int e;
int l;
}str[2000005];
int f[100005];
long long sum=0;
int co=0;
int b=0;
int cha(int x) //查
{
while(f[x]!=x)
{
x=f[x];
}
return x;
}
bool cmp(st a1,st b1)
{
return a1.l<b1.l;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&str[i].s,&str[i].e,&str[i].l);
}
sort(str+1,str+m+1,cmp); //排序
for(int i=1;i<=m;i++)
{
int x=cha(str[i].s);
int y=cha(str[i].e);
if(x==y)
{
continue;
}
f[y]=x;
sum+=str[i].l;
co++;
if(co==n-1) //最小生成的树干比结点少一个
{
printf("%lld\n",sum);
return 0;
}
}
if(co<n-1)//当不满足最小连通图,就orz
{
printf("orz");
return 0;
}
}
第二题:P1991 无线通讯网 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
我觉得这题有点难,不过看了许久后还是理解了
#include<bits/stdc++.h>
using namespace std;
int f[505];
int a[505];
int b[505];
int n=0;
struct st
{
double l;
int x;
int y;
}str[505*505];
int cha(int x)
{
while(f[x]!=x)
{
x=f[x];
}
return x;
}
bool cmp(st a1,st a2)
{
return a1.l<a2.l;
}
int main()
{
int s,p;
int ss=0;
scanf("%d%d",&s,&p);
for(int i=1;i<=p;i++)
{
f[i]=i;
}
for(int i=1; i<=p; i++)
{
scanf("%d%d",&a[i],&b[i]);
for(int j=1; j<i; j++)
{
n++;
str[n].l=sqrt((a[i]-a[j])*(a[i]-a[j])+ (b[i] - b[j]) * (b[i] - b[j]));
str[n].x=i;
str[n].y=j;
}
}
sort(str+1,str+n+1,cmp);
for(int i=1;i<=n;i++)
{
int j=cha(str[i].x),k=cha(str[i].y);
if(j!=k)
{
f[j]=k;
ss++;
if(ss==p-s)
{
printf("%.2lf\n",str[i].l);
return 0;
}
}
}
return 0;
}
第三题:P2121 拆地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题没有什么好说的,模版题,跟第一题差不多
#include<bits/stdc++.h>
using namespace std;
struct str
{
int s;
int e;
int l;
}arr[100010];
int f[100010];
long long sum=0;
int co=0;
int cha(int x)
{
while(f[x]!=x)
{
x=f[x];
}
return x;
}
bool cmp(str arr1,str arr2)
{
return arr1.l>arr2.l;
}
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&arr[i].s,&arr[i].e,&arr[i].l);
}
sort(arr+1,arr+m+1,cmp);
for(int i=1;i<=m;i++)
{
int x=cha(arr[i].s);
int y=cha(arr[i].e);
if(x==y)
{
continue;
}
f[y]=x;
sum+=arr[i].l;
co++;
if(co==k)
{
printf("%lld\n",sum);
return 0;
}
}
return 0;
}
第四题:P1396 营救 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
int f[100000005];
struct st
{
int s;
int e;
int l;
}str[100000005];
int cha(int x)
{
while(f[x]!=x)
{
x=f[x];
}
return x;
}
void bing(int x,int y)
{
if(x>y)
{
f[x]=y;
}
else
{
f[y]=x;
}
}
bool cmp(st a1,st a2)
{
return a1.l<a2.l;
}
int main()
{
int n,m,s,t;
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&str[i].s,&str[i].e,&str[i].l);
}
sort(str+1,str+1+m,cmp);
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=1;i<=m;i++)
{
int x=cha(str[i].s),y=cha(str[i].e);
if(x!=y)
{
bing(x,y);
if(cha(s)==cha(t))
{
printf("%d\n",str[i].l);
return 0;
}
}
}
return 0;
}
第五题:P1194 买礼物 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
int f[505];
struct st
{
int s;
int e;
int l;
}str[250005];
int cha(int x)
{
while(f[x]!=x)
{
x=f[x];
}
return x;
}
void bing(int x,int y)
{
if(x>y)
{
f[x]=y;
}
else
{
f[y]=x;
}
}
bool cmp(st a1,st a2)
{
return a1.l<a2.l;
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
int sum=0;
sum=a;
int h=0;
for(int i=1;i<=b;i++)
{
for(int j=1;j<=b;j++)
{
h++;
scanf("%d",&str[h].l);
str[h].s=i;
str[h].e=j;
if(str[h].l==0)
{
str[h].l=a;
}
}
}
sort(str+1,str+h+1,cmp);
for(int i=1;i<=b;i++)
{
f[i]=i;
}
for(int i=1;i<=h;i++)
{
int x=cha(str[i].s),y=cha(str[i].e);
if(x!=y)
{
bing(x,y);
sum+=min(str[i].l,a);
}
}
printf("%d\n",sum);
return 0;
}
第六题:P2872 [USACO07DEC] Building Roads S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
int f[1005];
int a[1005];
int b[1005];
int h=0;
struct st
{
double l;
int x;
int y;
}str[1005*1005];
int cha(int x)
{
while(f[x]!=x)
{
x=f[x];
}
return x;
}
void bing(int x,int y)
{
if(x>y)
{
f[x]=y;
}
else
{
f[y]=x;
}
}
bool cmp(st a1,st a2)
{
return a1.l<a2.l;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
for(int j=1;j<i;j++)
{
h++;
str[h].l=(double)sqrt((double)(a[i]-a[j])*(a[i]-a[j])+ (double)(b[i] - b[j]) * (b[i] - b[j]));
str[h].x=i;
str[h].y=j;
}
}
int c=0;
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=1;i<=m;i++)
{
int xx,yy;
scanf("%d%d",&xx,&yy);
bing(cha(xx),cha(yy));
}
sort(str+1,str+h+1,cmp);
double sum=0;
for(int i=1; i<=h; i++)
{
int xx,yy;
xx=cha(str[i].x);
yy=cha(str[i].y);
if(xx!=yy)
{
bing(xx,yy);
sum+=str[i].l;
c++;
if(c==n-m-1)
{
break;
}
}
}
printf("%.2lf\n",sum);
return 0;
}