kuangbin带你飞:点击进入新世界
最小生成算法模板:点击进入新世界
本人算是初学者中的初学者,欢迎交流~
感觉这个专题的难度比最短路还简单…可能是错觉吧…都是入门题,加深对算法的理解。
kuangbin的题型:
A.模板题 参考1.2.4.9.10
B.考察并查集 参考3.6.8
C.次小生成树 参考5
D. k条边免费(题型有点像最短路的分层图)参考7
kuangbin之外:
最小生成树模板
次小生成树模板
原题链接:传送门
思路:
#include
#include
#include
#define ll long long
#define R register int
using namespace std;
const int manx=200+5;
int n,m,u,v,w,k;
char c,cc;
int f[manx];
struct node{
int u,v,w;
}a[manx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
while(cin>>n&&n)
{
k=0;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<n;i++)
{
cin>>c>>m;
for(int i=1;i<=m;i++)
{
cin>>cc>>w;
a[++k].u=c-'A'+1;
a[k].v=cc-'A'+1;
a[k].w=w;
}
}
sort(a+1,a+1+k,cmp);
ll ans=0;
int total=1;
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
ans+=a[i].w;
f[u]=v;
total++;
if(total==n) break;
}
cout<<ans<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#define ll long long
#define R register int
using namespace std;
const int manx=200+5;
const int mamx=1e5+5;
int n,m,u,v,w,k;
int f[manx];
struct node{
int u,v,w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
while(cin>>n&&n)
{
k=0;
for(int i=1;i<=n;i++) f[i]=i;
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
a[++k].u=u;
a[k].v=v;
a[k].w=w;
}
sort(a+1,a+1+k,cmp);
ll ans=0;
int total=1;
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
ans+=a[i].w;
f[u]=v;
total++;
if(total==n) break;
}
cout<<ans<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#define ll long long
#define R register int
using namespace std;
const int manx=200+5;
const int mamx=1e5+5;
int n,m,u,v,w,k;
int f[manx];
struct node{
int u,v,w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
while(cin>>n&&n)
{
k=0;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++){
cin>>w;
if(j>i)
a[++k].u=i,a[k].v=j,a[k].w=w;
}
}
cin>>m;
ll ans=0;
int total=1;
for(int i=1;i<=m;i++){
cin>>u>>v;
u=find(u),v=find(v);
if(u!=v){
f[u]=v;
total++;
}
}
sort(a+1,a+1+k,cmp);
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
ans+=a[i].w;
f[u]=v;
total++;
if(total==n) break;
}
cout<<ans<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#define ll long long
#define R register int
using namespace std;
const int manx=200+5;
const int mamx=1e5+5;
int n,m,u,v,w,k;
int f[manx];
struct node{
int u,v,w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
while(cin>>n&&n)
{
k=0;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++){
cin>>w;
if(j>i)
a[++k].u=i,a[k].v=j,a[k].w=w;
}
}
sort(a+1,a+1+k,cmp);
ll ans=0;
int total=1;
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
ans+=a[i].w;
f[u]=v;
total++;
if(total==n) break;
}
cout<<ans<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=200+5;
const int mamx=1e5+5;
int n,m,u,v,w,k;
int f[manx],d[manx][manx];
vector<int>p[manx];
struct node{
int u,v,w;
bool vis;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
int t;
cin>>t;
while(t--)
{
k=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
p[i].clear();
p[i].push_back(i);
f[i]=i;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
a[++k].u=u,a[k].v=v,a[k].w=w,a[i].vis=false;
}
sort(a+1,a+1+k,cmp);
ll ans=0;
int total=1;
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
ans+=a[i].w;
f[u]=v;
a[i].vis=1;
total++;
int l1=p[u].size(),l2=p[v].size();
for(int j=0;j<l1;j++)
for(int k=0;k<l2;k++)
d[p[u][j]][p[v][k]]=d[p[v][k]][p[u][j]]=a[i].w;
for(int j=0;j<l1;j++) p[v].push_back(p[u][j]);
if(total==n) break;
}
ll res=inf;
for(int i=1;i<=k;i++)
if(!a[i].vis)
res=min(res,ans+a[i].w-d[a[i].u][a[i].v]);
if(res>ans) cout<<ans<<endl;
else cout<<"Not Unique!"<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=1e4;
const int mamx=5e6+5000;
int n,m,u,v,w,k;
int x[manx],y[manx],f[manx];
struct node{
int u,v,w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
scanf("%d",&n);
k=0;
for(int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
f[i]=i;
}
scanf("%d",&m);
int total=1;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
u=find(u),v=find(v);
if(u!=v){
f[u]=v;
total++; //连通时直接计算最小生成树集合里面的点数
}
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
u=find(i),v=find(j);
if(u==v) continue; //当边在最小生成树的集合里面跳过
w=(x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]);
a[++k].u=i,a[k].v=j,a[k].w=w;
}
sort(a+1,a+1+k,cmp);
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
f[u]=v;
total++;
cout<<a[i].u<<" "<<a[i].v<<endl;
if(total==n) break;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=1e3;
const int mamx=5e6+5000;
int n,m,u,v,w,k;
int x[manx],y[manx],f[manx];
struct node{
int u,v;
double w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
int t;
cin>>t;
while(t--){
scanf("%d%d",&n,&m);
k=0;
for(int i=1;i<=m;i++){
scanf("%d%d",&x[i],&y[i]);
f[i]=i;
}
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++)
{
double z=sqrt((x[i]-x[j])*(x[i]-x[j])*1.0+(y[i]-y[j])*(y[i]-y[j])*1.0);
a[++k].u=i,a[k].v=j,a[k].w=z;
}
sort(a+1,a+1+k,cmp);
int total=1;
double ans=0.00;
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
f[u]=v;
if(total==m-n){
ans=a[i].w;
break;
}
total++;
}
printf("%.2f\n",ans);
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=1e2+5;
const int mamx=1e5+5;
int n,m,u,v,w,k;
double x[manx],y[manx],z[manx],r[manx];
int f[manx];
struct node{
int u,v;
double w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
while(cin>>n&&n){
k=0;
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&x[i],&y[i],&z[i],&r[i]);
f[i]=i;
}
int total=1;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
double w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])+(z[i]-z[j])*(z[i]-z[j]))-r[i]-r[j];
if(w>0)a[++k].u=i,a[k].v=j,a[k].w=w;
else{
u=find(i),v=find(j);
if(u==v) continue;
f[u]=v;
total++;
}
}
sort(a+1,a+1+k,cmp);
double ans=0.000;
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
f[u]=v;
ans+=a[i].w;
total++;
if(total==n) break;
}
printf("%.3lf\n",ans);
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=1e2+5;
const int mamx=1e5+5;
int n,m,u,v,w,k;
int f[manx];
struct node{
int u,v,w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
while(cin>>n&&n){
k=0;
m=n*(n-1)/2;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
for(int i=1;i<=n;i++) f[i]=i;
int total=1;
ll ans=0;
sort(a+1,a+1+m,cmp);
for(int i=1;i<=m;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
f[u]=v;
ans+=a[i].w;
total++;
if(total==n) break;
}
printf("%d\n",ans);
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=1e2+5;
const int mamx=1e5+5;
int n,m,u,v,w,k;
int x[manx],y[manx];
int f[manx];
struct node{
int u,v;
double w;
}a[mamx];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
int main()
{
int t;
cin>>t;
while(t--){
scanf("%d",&n);
k=0;
for(int i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
double ww=sqrt((x[i]-x[j])*(x[i]-x[j])*1.000+(y[i]-y[j])*(y[i]-y[j]));
if(ww>1000||ww<10) continue;
a[++k].u=i,a[k].v=j,a[k].w=ww*100;
}
int total=1;
double ans=0;
sort(a+1,a+1+k,cmp);
for(int i=1;i<=k;i++)
{
u=find(a[i].u),v=find(a[i].v);
if(u==v) continue;
f[u]=v;
ans+=a[i].w;
total++;
}
if(total==n) printf("%.1lf\n",ans);
else puts("oh!");
}
return 0;
}