社区讨论

正解为何20pts 求调或hack数据

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

讨论操作

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

当前回复
7 条
当前快照
1 份
快照标识符
@mhiy40dg
此快照首次捕获于
2025/11/03 17:36
4 个月前
此快照最后确认于
2025/11/03 17:36
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
constexpr int N=1e4+5;
constexpr int M=1e6+7;
typedef long long ll;
int n,m,k;
struct edge{
    int u,v,w;
    bool operator <(const edge &x)const{return w<x.w;}
} res[M+N*10];
int fa[N+50];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int c[11];
bitset<11> pd;
signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++) cin>>res[i].u>>res[i].v>>res[i].w;
    sort(res+1,res+1+m);
    for(int i=1;i<=n;i++) fa[i]=i;
    int tot=0;
    ll ans=0;
    for(int i=1;i<=m;i++){
        int u=find(res[i].u),v=find(res[i].v);
        if(u==v) continue;
        fa[u]=v;ans+=res[i].w;
        if(++tot==n-1) break;
    }
    int pointtot=n,edgetot=n-1;
    for(int i=1;i<=k;i++){
        cin>>c[i];
        // cout<<"c"<<" "<<c[i]<<'\n';
        for(int j=1;j<=n;j++){
            int t;cin>>t;
            res[++edgetot]={n+i,j,t};
            // cout<<"insert"<<n+i<<" "<<j<<" "<<t<<'\n';
        }
    }
    sort(res+1,res+1+edgetot);
    // for(int i=1;i<=edgetot;i++) cout<<res[i].u<<" "<<res[i].v<<" "<<res[i].w<<'\n';
    // cout<<pointtot<<" "<<edgetot<<" "<<ans;
    for(int dp=1;dp<(1<<k);dp++){
        // cout<<"dp"<<" "<<dp<<'\n';
        tot=0;
        pointtot=n;
        pd.reset();
        ll now=0;
        for(int i=0;i<k;i++){
            if((dp>>i)&1){
                pointtot++;now+=c[i+1];pd[i+1]=1;
            }
        }
        if(now>ans) continue;
        for(int i=1;i<=n+k;i++) fa[i]=i;
        // cout<<pointtot<<" "<<edgetot<<'\n';
        for(int i=1;i<=edgetot;i++){
            if(res[i].u>n&&!pd[res[i].u-n]) continue;
            int u=find(res[i].u),v=find(res[i].v);
            if(u==v) continue;
            // cout<<res[i].u<<" "<<res[i].v<<" "<<res[i].w<<'\n';
            fa[u]=v;
            now+=res[i].w;
            if(++tot==pointtot-1) break;
        }
        ans=min(ans,now);
        // cout<<ans<<'\n';
    }
    cout<<ans;
    return 0;
}

回复

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

正在加载回复...