[USACO08OCT]:打井Watering Hole(MST)

题意:有N个牧场,每个牧场修水井花费Wi,连接牧场花费Pij,问最小花费,使得每个牧场要么有水井,要么和有水井的牧场有通道。

思路:加一个格外的节点O,连接O表示修井,边权是修井的费用。     那么这N+1个点求最MST即可。

刘同学想到的解法: 先找到修井费用最低的的牧场,然后和上面一样,由于最低的那个必选,所以异曲同工。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=310;
const int maxm=maxn*maxn;
int fa[maxn],t[maxn],a[maxn][maxn],tot;
struct in{
    int len,u,v;
}s[maxm];
bool cmp(in w,in q) {
    return w.len<q.len;
}
void add(int u,int v,int len){
    tot++; s[tot].u=u; s[tot].v=v;
    s[tot].len=len;
}
int find(int x){
    if(x!=fa[x]) return fa[x]=find(fa[x]);
    return x;
}
int main()
{
    int N,M,ans=0;
    scanf("%d",&N);
    rep(i,1,N) scanf("%d",&t[i]);
    rep(i,1,N) rep(j,1,N) {
        scanf("%d",&a[i][j]);
        if(a[i][j]) add(i,j,a[i][j]);
    }
    rep(i,0,N) fa[i]=i;
    rep(i,1,N) add(0,i,t[i]);
    sort(s+1,s+tot+1,cmp);
    rep(i,1,tot) {
        int fu=find(s[i].u);
        int fv=find(s[i].v);
        if(fu==fv) continue;
        fa[fu]=fv; ans+=s[i].len;
     }
     printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/11164702.html

时间: 2024-10-18 00:38:37

[USACO08OCT]:打井Watering Hole(MST)的相关文章

P1550 [USACO08OCT]打井Watering Hole

P1550 [USACO08OCT]打井Watering Hole 题目比较简单,却提醒了图论建图的的重要性. 很多时候建图不只是要将给定的信息建立,还需要添加辅助点. 不过这题是真水 #include<cstdio> #include<algorithm> #include<iostream> #include<cstring> using std::sort; const int maxn=500; struct node { int A,B; int

luogu P1550 [USACO08OCT]打井Watering Hole

题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to his N (1 <= N <= 300) pastures which are conveniently numbered 1..N. He may bring water to a pasture either by building a well in that pasture or connecting the pasture via a pipe to

题解 P1550 【[USACO08OCT]打井Watering Hole】

题面(翻译有点问题,最后一句话) 农民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 需要为使所有农场都与有水的农场相连或拥有水井所需要的钱数. 题意 有n个点,每个点之间都有边权,但是每个点也

『USACO08OCT]』Watering Hole

题面 code 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,cnt,ans,fa[305]; 4 struct edge{int x,y,v;}e[100005]; 5 inline int read() { 6 int x=0,f=1; char c=getchar(); 7 while(c<'0'||c>'9') {if(c=='-')f=-1; c=getchar();} 8 while(c>='0'

HDU 2887 Watering Hole(MST + 倍增LCA)

传送门 总算是做上一道LCA的应用题了... 题意:有$n$个牧场, $m$根管道分别连接编号为$u,v$的牧场花费$p_{i}$,在第$i$个牧场挖口井需要花费$w_{i}$,有$P$根管道直接连通着$u,v$,即免费连上$u,v$ 对每根免费管道输出让所有牧场都有水的最小花费 先是最小生成树,用0去连每一个点,边权就是每个点的权值,然后正常建,跑一遍最小生成树,把用到的边重新建一次图,然后就对每次询问的$u,v$,减掉他们之间的路径的最长边就是答案了 因为删去这其中一条边,再免费连上$u,v

usaco oct09 Watering Hole

Farmer John希望把水源引入他的N (1 <= N <= 300) 个牧场,牧场的编号是1~N.他将水源引入某个牧场的方法有两个,一个是在牧场中打一口井,另一个是将这个牧场与另一个已经有水源的牧场用一根管道相连.在牧场i中打井的费用是W_i (1 <= W_i <= 100000).把牧场i和j用一根管道相连的费用是P_ij (1 <= P_ij <= 100000, P_ij = P_ji, P_ii = 0).请你求出Farmer John最少要花多少钱才能

USACO 2008 Watering hole Prim

题目 题目描述 Farmer John has decided to bring water to his N (1 <= N <= 300) pastures which are conveniently numbered 1..N. He may bring water to a pasture either by building a well in that pasture or connecting the pasture via a pipe to another pasture

并查集题目整理

并查集 之前写最小生成树的时候对这一部分的知识也并没有十分详细的整理 近天做了一些用到并查集的题目,来整理一下 知识回顾 首先,先来回顾一下有关并查集的内容 <1> 定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并. <2>初始化 把每个点所在集合初始化为其自身. 通常来说,这个步骤在每次使用该数据结构时只需要执行

poj 2182 Lost Cows

Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9536   Accepted: 6146 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'waterin