专栏文章
国庆day2考试总结--下午
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minovhl5
- 此快照首次捕获于
- 2025/12/02 05:56 3 个月前
- 此快照最后确认于
- 2025/12/02 05:56 3 个月前
前言
芭比Q了
problem A
模板题,但是我没有写对,原因是我没有判断<C和判断-1时条件出错
problem.A 正确代码
CPP#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+5;
struct node
{
int x,y,w;
}e[N];
bool cmp(node e,node b)
{
return e.w<b.w;
}
int fa[N],x[N],y[N];
int find(int x)
{
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
void unionn(int x,int y)
{
x=find(x),y=find(y);
if(x==y)return ;
fa[x]=y;
}
int n,k,cnt;
void kruskal()
{
sort(e+1,e+1+cnt,cmp);
int ans=0,sum=0;
for(int i=1;i<=cnt;i++)
{
if(find(e[i].x)==find(e[i].y))continue;
unionn(e[i].x,e[i].y);
ans++;
sum+=e[i].w;
}
if(ans<n-1)cout<<"-1";
else cout<<sum;
}
signed main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
int nx=x[i],ny=y[i];
for(int j=1;j<i;j++)
{
int zx=x[j],zy=y[j];
int ans=(nx-zx)*(nx-zx)+(ny-zy)*(ny-zy);
if(ans>=k)
{
cnt++;
e[cnt].x=i;
e[cnt].y=j;
e[cnt].w=ans;
}
}
}
kruskal();
return 0;
}
problem B
依旧模板题,但是我忘记在kruskal函数里面把e[i].x和e[i].y合并了
CPP#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int fa[N],x[N],y[N],n;
struct node
{
int x,y,w;
}e[N];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(fa[x]==x)return fa[x];
return fa[x]=find(fa[x]);
}
void unionn(int x,int y)
{
x=find(x),y=find(y);
if(x==y)return ;
fa[x]=y;
return ;
}
int cnt;
void kruskal()
{
sort(e+1,e+1+cnt,cmp);
int ans=0,sum=0;
for(int i=1;i<=cnt;i++)
{
int x=find(e[i].x),y=find(e[i].y);
if(x==y)continue;
ans++;
unionn(e[i].x,e[i].y);
sum=e[i].w;
}
cout<<sum;
return ;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)continue;
cnt++;
e[cnt].x=i;
e[cnt].y=j;
e[cnt].w=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
}
kruskal();
return 0;
}
problem C
主要是数组原因,然后就是vector push和size求错(下次肯定用数组),再加上输出是<号少写了一个导致CE,其他都想得一摸一样
problem C 正确代码
CPP#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e6+5,M=2005;
int fa[M],a[M],b[M],x[M],y[M],c[M],k[M],n,cnt;
struct node
{
int x,y,w,id;
}e[N];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(fa[x]==x)return fa[x];
return fa[x]=find(fa[x]);
}
void unionn(int x,int y)
{
x=find(x),y=find(y);
if(x==y)return ;
fa[x]=y;
}
int m;
void kruskal()
{
for(int i=0;i<=n;i++)fa[i]=i;
sort(e+1,e+1+m,cmp);
int sum=0,cnt=0,num=0,l=0,r=0,ans=0;
for(int i=1;i<=m;i++)
{
int x=find(e[i].x),y=find(e[i].y);
if(x==y)continue;
unionn(x,y);
if(e[i].x==0)a[++l]=e[i].y;
else b[++r]=e[i].x,c[r]=e[i].y;
sum+=e[i].w;
cnt++;
if(cnt>n-1)break;
}
cout<<sum<<"\n";
cout<<l<<"\n";
for(int i=1;i<=l;i++)cout<<a[i]<<" ";
cout<<'\n';
cout<<r<<"\n";
for(int i=1;i<=r;i++)cout<<b[i]<<" "<<c[i]<<"\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
for(int i=1;i<=n;i++)cin>>c[i];
for(int i=1;i<=n;i++)cin>>k[i];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)continue;
int d=abs(x[i]-x[j])+abs(y[i]-y[j]);
e[++m]=node{i,j,d*(k[i]+k[j]),0};
}
}
for(int i=1;i<=n;i++){
m++;
e[m].x=0;
e[m].y=i;
e[m].w=c[i];
e[m].id=i;
}
kruskal();
return 0;
}
problem D
试了一下用贪心能拿35分(甚至还高,但是我只拿了35),正确解法最容易想的是prim,但是没学,所以只能用kruskal,看完题目,连通块需要是一片连续的,所以我们尽量把它向右合并,让它的根节点在区间右侧,那么遍历的时候就能快速的访问区间内的所有连通块
END(AFO了)
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...