zoukankan      html  css  js  c++  java
  • 洛谷 题解 P1550 【[USACO08OCT]打井Watering Hole】

    本题看似很难,实际上思路非常简单——如果你想通了。

    首先有一个问题:图中有几个点?大部分的人会回答(n)个点。错了,有(n+1)个。

    多出来的那个点在哪?关键在于你要理解每一个决策的意义。实际上,多出来的那个点是地下的天然矿泉水。当我们打井时,我们实际上是在往地下连边。理解了这一点,代码就没有任何难度了。

    构图时,我们只需多加一个点,对于每个点(i),我们连边(i→n+1),边权为(w_i)。然后直接跑最小生成树就没了。就没了。(转载from here)

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=300+10;
    const int MAXM=1e5;
    int n,m;
    int fa[MAXN];
    struct Node
    {
    	int u,v,w;
    	bool operator < (const Node &x) const
    	{
    		return x.w>w;
    	}
    }edge[MAXM];
    inline int read()
    {
    	int tot=0;
    	char c=getchar();
    	while(c<'0'||c>'9')
    		c=getchar();
    	while(c>='0'&&c<='9')
    	{
    		tot=tot*10+c-'0';
    		c=getchar();
    	}
    	return tot;
    }
    inline int find(int k)
    {
    	if(fa[k]==k)return k;
    	else return fa[k]=find(fa[k]);
    }
    inline int kruskal()
    {
    	int tot=0,cnt=0;
    	for(int i=1;i<=n;i++)
    		fa[i]=i;
    	for(int i=1;i<=m;i++)
    	{
    		int fx=find(edge[i].u),fy=find(edge[i].v);
    		if(fx!=fy)
    		{
    			fa[fx]=fy;
    			tot++;
    			cnt+=edge[i].w;
    		}
    		if(tot==n-1)return cnt;
    	}
    }
    int main()
    {
    	n=read();
    	int x;
    	for(int i=1;i<=n;i++)
    	{
    		x=read();
    		edge[++m].u=i;
    		edge[m].v=n+1;
    		edge[m].w=x;
    	}
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			x=read();
    			if(i<j)
    			{
    				edge[++m].u=i;
    				edge[m].v=j;
    				edge[m].w=x;
    			}
    		}
    	}
    	n++;
    	sort(edge+1,edge+1+m);
    	printf("%d
    ",kruskal());
    	return 0;
    }
    
  • 相关阅读:
    springboot+fegin实现负载均衡
    springcloud实现微服务服务注册、负载均衡
    spring boot服务状态监控+shell远程连接服务
    微服务基础概念及相关技术组件
    集群分布式基础概念及了解
    http第一章-telnet测试
    spring整合netty

    springMVC+spring+JPA配置文件
    CAN信号值解析
  • 原文地址:https://www.cnblogs.com/hulean/p/11128642.html
Copyright © 2011-2022 走看看