• Luogu P1550[USACO08OCT]打井Watering Hole


    Description:

    农民John 决定将水引入到他的n(1<=n<=300)个牧场。他准备通过挖若干井,并在各块田中修筑水道来连通各块田地以供水。在第i 号田中挖一口井需要花费W_i(1<=W_i<=100,000)元。连接i 号田与j 号田需要P_ij (1 <= P_ij <= 100,000 , P_ji=P_ij)元。请求出农民John 需要为使所有农场都与有水的农场相连或拥有水井所需要的钱数。

    Analysis:

    我们可以转换一下思路,把每个点的点权当成一个指向自己的边权,然后构造一棵最小生成树就好了!

    Code

    注意数组大小!

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define N 500
    using namespace std;
    struct edge{
    	int from,to,w;
    	bool operator < (const edge &a) const {
    		return w < a.w;
    	}
    }e[100001];
    int set[N],w[N],num_edge,n;
    inline void add(int from,int to,int w)
    {
    	e[++num_edge].from = from;
    	e[num_edge].to = to;
    	e[num_edge].w = w;
    }
    int findset(int x)
    {
    	if(set[x] == x) return x;
    	return set[x] = findset(set[x]);
    }
    void unionset(int a,int b)
    {
    	a = findset(a);
    	b = findset(b);
    	set[a] = b;
    }
    void solve()
    {
    	sort(e + 1,e + 1 + num_edge);
    	int k = 0,ans = 0;
    	for(int i = 1;i <= num_edge;++i)
    	{
    		int a = e[i].from,b = e[i].to;
    		if(findset(a) != findset(b))
    		{
    			unionset(a,b);
    			++k;
    			ans += e[i].w;
    		}
    		if(k == n) break;
    	}
    	printf("%d
    ",ans);
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i = 1;i <= n;++i)
    	{
    		scanf("%d",&w[i]);
    		set[i] = i;
    		add(0,i,w[i]);
    	}
    	for(int i = 1;i <= n;++i)
    	{
    		for(int j = 1;j <= n;++j)
    		{
    			int v;
    			scanf("%d",&v);
    			if(i > j)
    			{
    				add(i,j,v);
    			}
    		}
    	}	
    	solve();
    	return 0;
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    python 协程之Greenlet
    python 协程
    python 多进程通信之Manger
    python 多线程通信之Queue
    python 多进程
    python threading之queue
    python threading之同步条件(Event)
    python threading之条件变量同步(condition)
    python之字符串常用方法
    python之字典操作
  • 原文地址:https://www.cnblogs.com/Zforw/p/10809978.html
Copyright © 2020-2023  润新知