自己写了个代码,锣鼓洛谷上显示91分(#1TLE)。看了下和我的思路相似的第一篇题解,因为好奇(可能有吧),就修改了一下头文件交上去了(绝对没想抄题解),结果也是91分。
我的代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
char ch=getchar();int x=0,f=1;
while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,k,a[100000],fa[100000],s[100000],f[100000],cnt=0,ans=999999999,minn=999999999;
int find(int x){
if (x==fa[x])return x;
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
if (find(x)!=find(y)){
a[find(y)]+=a[find(x)];
fa[find(x)]=find(y);
}
}
signed main(){
n=read(),m=read(),k=read();
for (int i=1;i<=n;i++){fa[i]=i;a[i]=1;}
for (int i=1;i<=k;i++){
int x=read(),y=read();
merge(x,y);
}
for (int i=1;i<=n;i++){
if (fa[i]==i){
s[++cnt]=a[i];
}
}
for (int i=1;i<=cnt;i++){
for (int j=2*m;j>=s[i];j--){
f[j]=max(f[j],f[j-s[i]]+s[i]);
}
}
for (int i=0;i<=2*m;i++){
if (minn>abs(f[i]-m)){
minn=abs(f[i]-m);
ans=f[i];
}
}
if (ans==999999999)printf("0");
else printf("%lld",ans);
return 0;
}
我交的类似的代码:
#include<bits/stdc++.h>
using namespace std;
int fa[100000],p[100000],x,y,k,m,n,s[100000],f[100000],cnt;
int find(int u){
if(fa[u]==u) return u;
else return fa[u]=find(fa[u]);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)fa[i]=i,p[i]=1;
for(int i=1;i<=k;i++){
scanf("%d%d",&x,&y);
int u=find(x);int v=find(y);
if(u!=v)fa[u]=v,p[v]+=p[u];
}
for(int i=1;i<=n;i++)
if(fa[i]==i){
cnt++;
s[cnt]=p[i];
}
for(int i=1;i<=cnt;i++)
for(int j=2*m;j>=s[i];j--)
f[j]=max(f[j],f[j-s[i]]+s[i]);
int ans=999999999,minn=999999999;
for(int i=1;i<=2*m;i++){
if(minn>abs(f[i]-m))minn=abs(f[i]-m),ans=f[i];
}
if(ans==999999999) printf("0");
else printf("%d",ans);
return 0;
}
一脸懵逼。 想要问下大佬们第一篇题解是不是有问题?或者说应该怎么改?