社区讨论

求问复杂度

P14362[CSP-S 2025] 道路修复参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mhpi1ebh
此快照首次捕获于
2025/11/08 07:41
4 个月前
此快照最后确认于
2025/11/08 07:41
4 个月前
查看原帖
下面代码的复杂度多少?预期获得多少分?我认为它虽然不是正解,但是不应该只获得 40 分。常数问题还是我复杂度分析有问题?以及有没有简单的优化?
CPP
#include<iostream>
#include<algorithm>
using namespace std;
inline char gc(){
	static char BB[1<<20],*S=BB,*T=BB;
	return S==T&&(T=(S=BB)+fread(BB,1,1<<20,stdin),S==T)?EOF:*S++;
}
inline int read(){
	int x=0;char ch=gc();
	while(ch<48) ch=gc();
	while(ch>=48) x=(x<<3)+(x<<1)+(ch^48),ch=gc();
	return x;
}
const int N=1e4+10,M=1.1e6+10,K=15;
int n,m,k;
struct node{int x,y,z;}a[M],b[M];
int c[K],d[K][N];
int c1[K],cnt;
int f[N];
int Find(int x){
	if(f[x]==x) return x;
	return f[x]=Find(f[x]);
}
bool cmp(node x,node y){return x.z<y.z;}
long long sum,ans=1e18;int tot,num;
void kruskal(){
	for(int i=1;i<=n+cnt;i++) f[i]=i;num=0;
	sort(b+1,b+1+tot,cmp);
	for(int i=1;i<=tot;i++){
		int xx=Find(b[i].x),yy=Find(b[i].y);
		if(xx==yy) continue;
		f[xx]=yy;
		sum+=b[i].z;
		if(++num==n+cnt-1||sum>ans) break;
	}
}
int main(){
	// freopen("road.in","r",stdin);
	// freopen("road.out","w",stdout);
	n=read();m=read();k=read();
	for(int i=1;i<=m;i++) a[i].x=read(),a[i].y=read(),a[i].z=read();
	for(int i=1;i<=k;i++){
		c[i]=read();
		for(int j=1;j<=n;j++) d[i][j]=read();
	}
	for(int p=0;p<=(1<<k);p++){
		for(int i=1;i<=m;i++) b[i]=a[i];
		sum=cnt=0;
		for(int i=1;i<=k;i++) if((p>>(i-1))&1) c1[++cnt]=i,sum+=c[i];
		if(sum>ans) continue;
		tot=m;
		for(int i=1;i<=cnt;i++) for(int j=1;j<=n;j++){
			tot++;b[tot].x=n+i;b[tot].y=j;b[tot].z=d[c1[i]][j];
		}
		kruskal();
		ans=min(ans,sum);
	}
	cout<<ans;
	return 0;
}


回复

3 条回复,欢迎继续交流。

正在加载回复...