1 条题解

  • 0
    @ 2026-4-7 20:34:54

    这是最小生成树模板题。

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    int read()
    {
    	int x=0;
    	bool neg=false;
    	char c=getchar_unlocked();
    	while(c<'0')
    	{
    		if(c=='-') neg=true;
    		c=getchar_unlocked();
    	}
    	while(c>='0')
    	{
    		x=x*10+c-'0';
    		c=getchar_unlocked();
    	}
    	if(neg) return -x;
    	return x;
    }
    void write(int x)
    {
    	if(x<0)
    	{
    		putchar_unlocked('-');
    		write(-x);
    		return;
    	}
    	if(x<=9)
    	{
    		putchar_unlocked(x+'0');
    		return;
    	}
    	write(x/10);
    	putchar_unlocked(x%10+'0');
    }
    struct R
    {
    	int ld[10012],sz[10012];
    	void init(int n)
    	{
    		for(int i=1;i<=n;i++)
    		{
    			ld[i]=i;
    			sz[i]=1;
    		}
    	}
    	int want(int x)
    	{
    		if(ld[x]==x) return x;
    		int c=want(ld[x]);
    		ld[x]=c;
    		return c;
    	}
    	bool add(int x,int y)
    	{
    		x=want(x);
    		y=want(y);
    		if(x==y) return false;
    		if(sz[y]>sz[x]) swap(x,y);
    		ld[y]=x;
    		sz[x]+=sz[y];
    		sz[y]=0;
    		return true;
    	}
    };
    struct M
    {
    	int x;
    	int y;
    	int z;
    };
    R r;
    M e[1000012];
    bool cmp(M x,M y)
    {
    	return x.z<y.z;
    }
    int c[12];
    bool dis[10012];
    int get(int n1,int n2)
    {
    	r.init(n1);
    	int lf=n2-1,ans=0,i=1;
    	while(lf)
    	{
    		if(!dis[e[i].x]&&!dis[e[i].y]&&r.add(e[i].x,e[i].y))
    		{
    			lf--;
    			ans+=e[i].z;
    		}
    		i++;
    	}
    	return ans;
    }
    int search(int u,int v,int w,int n)
    {
    	if(u>v) return get(n+v,n+w);
    	dis[u+n]=false;
    	int ans=c[u]+search(u+1,v,w+1,n);
    	dis[u+n]=true;
    	ans=min(ans,search(u+1,v,w,n));
    	return ans;
    }
    signed main()
    {
    	int T=1;
    	while(T--)
    	{
    		int n=read(),m=read(),k=0;
    		for(int i=1;i<=m;i++)
    			e[i]=(M){read(),read(),read()};
    		sort(e+1,e+m+1,cmp);
    		r.init(n);
    		for(int i=1;i<=m;i++)
    			if(!r.add(e[i].x,e[i].y)) e[i].z=1e18;
    		sort(e+1,e+m+1,cmp);
    		while(e[m].z>1e17)
    		{
    			e[m]=(M){0,0,0};
    			m--;
    		}
    		for(int i=1;i<=k;i++)
    		{
    			cin>>c[i];
    			for(int j=1;j<=n;j++)
    			{
    				m++;
    				e[m]=(M){n+i,j,read()};
    			}
    		}
    		sort(e+1,e+m+1,cmp);
    		write(search(1,k,0,n));
    		putchar_unlocked('\n');
    	}
    	return 0;
    }
    
    • 1

    [2026 February TFOJ Normal Round] Minimum Spanning Tree

    信息

    ID
    251
    时间
    1000ms
    内存
    512MiB
    难度
    6
    标签
    递交数
    2
    已通过
    2
    上传者