zoukankan      html  css  js  c++  java
  • 题解 P2916 【[USACO08NOV]Cheering up the Cow G】

    [USACO08NOV]Cheering up the Cow G

    核心算法:Kruskal

    题目中说:“删去尽可能多的边”。就是指保留一棵最小生成树。


    构图

    我们取一小段来分析一下:

    (可以把这个理解为单位元

    a8CtXQ.png

    按照题目中的意思,走过这一张的花费为:

    C[1] + L + C[2] + L + C[1]

    即:C[1] + C[1] + 2L + C[2]

    a89RFP.png

    走过这一张的花费为:

    C[1] + L(1,2) + C[2] + L(2,3) + C[3] + L(2,3) + C[2] + L(1,2) + C[1]

    即:C[1] + (C[1] + 2L(1,2) + C[2]) + (C[2] + 2L(2,3) + C[3])

    所以,我们可以推出:新的边的权值,为这条边 起点权值+终点权值+两倍边权

    而最后的结果,还要加上一开始起点权值。 (即取点权中的最小值,因为题目中要求最小)

    代码如下(细节见注释):

    #include <bits/stdc++.h>
    #define MAXN 1000000
    #define INF 0x3f3f3f3f
    int fat[MAXN],siz[MAXN];
    int c[MAXN],n,m,ans=0;
    struct EDGE{int from,to,val;}	e[MAXN];
    //邻接矩阵 
    bool cmp(EDGE x,EDGE y){return x.val<y.val;}
    //比较器  按照边的权值排序 
    int Find(int x)	{return (fat[x]==x) ? x :fat[x]=Find(fat[x]);}
    void unionn (int x,int y)
    {
    	x=Find(x); y=Find(y);
    	if(siz[x]>siz[y]) std::swap(x,y);
    	fat[x]=y;	siz[y]+=siz[x];
    }
    //并查集模板 
    bool kruskal()
    {
    	int k=0;
    	std::sort(e+1,e+m+1,cmp);
    	for(int i=1;i<=m;++i)
    	{
    		if(k==n-1)	break;
    		if(Find(e[i].to)!=Find(e[i].from))
    		{
    			unionn(e[i].to,e[i].from);
    			++k;	ans+=e[i].val;
    		}
    	}
    	return (k==n-1);
    }
    // kruskal模板 
    int main()
    {
    	int minn=INF;
    	std::scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)	{fat[i]=i;	siz[i]=1;}
    	//并查集初始化  
    	for(int i=1;i<=n;++i)
    	{
    		std::scanf("%d",&c[i]);
    		minn=std::min(minn,c[i]);
    		//点权值中取最小值 
    	}
    	for(int i=1;i<=m;++i)
    	{
    		std::scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].val);
    		e[i].val=e[i].val*2+c[e[i].from]+c[e[i].to];
    		//重新定义权值 
    	}
    	if(kruskal()) std::printf("%d",ans+minn);
    	return 0;
    }
    
  • 相关阅读:
    c#无边框窗体移动 屏蔽双击最大化
    怎么样让代码都带有注释?
    权限设置相关,利用Microsoft.Win32.Security
    计算几何常用算法概览[转]
    VS 常见快捷键
    关于读取txt文件的分段问题
    ajax 常用方法
    文件以附件形式下载的方法
    半角和全角互换
    在ubuntu 中安装 jsdoc
  • 原文地址:https://www.cnblogs.com/cyl-oi-miracle/p/13414610.html
Copyright © 2011-2022 走看看