社区讨论

92pts想进行优化,玄关

题目总版参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mhpi77uu
此快照首次捕获于
2025/11/08 07:45
3 个月前
此快照最后确认于
2025/11/08 07:45
3 个月前
查看原帖
以下是我考后复盘写的代码,考场上写的因为没有先把原图的最小生成树求出,效率更低。估计是算法问题,想知道正解或优化办法。码风难看,还请见谅。
CPP
#include<bits/stdc++.h>
using namespace std;
struct p {
	int u;
	int v;
	int w;
} e[1000010],adde[100010],ee[10001];
int n,m,k,tot2;
long long ans1=1e18+7;
vector<int> c[14];
int fa[110010];
int findfa(int x) {
	if(x==fa[x])
		return x;
	else
		return x=findfa(fa[x]);
}
bool cmp(p a,p b) {
	return a.w<b.w;
}
long long check(int nn,int mm) {
	int tot=n,t=n;
	long long ans=0;
	int n1=nn;
	while(nn>0) {
		t++;
		if(nn%2==1) {

			tot++;
			ans+=c[t-n][0];
			for(int i=1; i<=n; i++) {
				adde[++mm].u=i,adde[mm].v=t,adde[mm].w=c[t-n][i];
			}
		}
		nn/=2;
	}

	sort(adde+1,adde+1+mm,cmp);

	for(int i=1; i<=n+k; i++)
		fa[i]=i;

	int count=1,count1=1,size=0;
	for(int i=1; i<=m+mm; i++) {
		p ls;
		if((e[count].w<=adde[count1].w&&count<=m)||(count1>mm)) {
			ls=e[count];
			count++;
		} else if((e[count].w>adde[count1].w&&count1<=mm)||(count>m)) {
			ls=adde[count1];
			count1++;
		}
		int gx=findfa(ls.u),gy=findfa(ls.v);
		if(gx==gy)
			continue;
		else {
			fa[gy]=gx;
			ans+=ls.w;
			if(ans>ans1)
				break;
			size++;
			if(n1==0)
				ee[++tot2]=ls;
			if(size==tot-1)
				break;

		}
	}
	return ans;
}
int main() {
	//ifstream cin("road.in");
	ios::sync_with_stdio(false);
	cin>>n>>m>>k;
	for(int i=1; i<=m; i++)
		cin>>e[i].u>>e[i].v>>e[i].w;
	sort(e+1,e+1+m,cmp);

	ans1=check(0,0);
	memcpy(e,ee,sizeof(ee));
	m=tot2;
	bool pf=0;
	for(int i=1,t; i<=k; i++) {
		cin>>t;
		if(t!=0)
			pf=1;
		c[i].push_back(t);
		for(int j=1,x; j<=n; j++) {
			cin>>x;
			c[i].push_back(x);
		}
	}
	int p=pow(2,k),i=1;
	if(!pf&&k>=5&&k<=10)
		i=p-1;
	for( i; i<p; i++) {
		ans1=min(ans1,check(i,0));
	}
	cout<<ans1;
	return 0;
}

回复

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

正在加载回复...