洛谷P1550 打井
生活随笔
收集整理的這篇文章主要介紹了
洛谷P1550 打井
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目背景:考完試回來發現了一道原題QAQ
題目背景
John的農場缺水了!!!
題目描述
農民John 決定將水引入到他的n(1<=n<=300)個牧場。他準備通過挖若
干井,并在各塊田中修筑水道來連通各塊田地以供水。在第i 號田中挖一口井需要花費W_i(1<=W_i<=100,000)元。連接i 號田與j 號田需要P_ij (1 <= Pi,jP_{i,j}Pi,j? <= 100,000 , Pj,iP_{j,i}Pj,i?=Pi,jP_{i,j}Pi,j?)元。
請求出農民John 需要為使所有農場都與有水的農場相連或擁有水井所需要的錢數。
輸入輸出格式
輸入格式:
第1 行為一個整數n。
第2 到n+1 行每行一個整數,從上到下分別為W_1 到W_n。
第n+2 到2n+1 行為一個矩陣,表示需要的經費(P_ij)。
輸出格式:
只有一行,為一個整數,表示所需要的錢數。
輸入輸出樣例
輸入樣例#1:
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
輸出樣例#1:
9
說明
John等著用水,你只有1s時間!!!
做法:另類的最小生成樹啊就是!
為什么在考場上沒想出來??
只要設立一個虛點用來存點權就好了!!
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm>using namespace std ; int read(){ //快讀int x = 0 ;int f = 1 ; char s= getchar() ;while(s>'9'||s<'0') {if(s=='-')f=-1;s=getchar();}while(s<='9'&&s>='0') {x=x*10+(s-'0');s=getchar();}return x*f ; } int n ; int w[500] ; struct dy{//結構體int x , y , z ; }a[200010];int t ; void add(int x , int y,int z) {a[++t].x = x ;a[t].y = y ;a[t].z = z ; }int vis[500][500] ; int fa[500] ; int find(int x) {if(fa[x] != x ) fa[x] = find(fa[x]) ;return fa[x] ; } void unionn(int x , int y ) {x = find(x) ;y = find(y) ;fa[x] = y ; } int cmp(dy x , dy y) {return x.z < y.z ; } int main(){n = read() ;for(int i = 1 ; i <= n ; i++) {w[i] = read() ;add(0,i,w[i]) ;//存放點權}for(int i = 1 ; i <= n ; i ++) {for(int j = 1 ; j <= n ; j ++) {int x ;x = read() ;if(i == j) continue ;//為了防止出現BUG,當有向圖來存if(vis[i][j]) continue ;vis[i][j] = 1 ;add(i,j,x) ;}}int tot = 0, k = 0 ;sort(a+1,a+1+t,cmp) ;for(int i = 0 ; i <= n ; i ++) fa[i] = i ;for(int i = 1 ; i <= t ; i ++) {//kruskal 算法if(find(a[i].x) != find(a[i].y)) {unionn(a[i].x , a[i].y) ;k ++ ;tot += a[i].z ;}if(k == n) break ;} printf("%d\n",tot) ;return 0; }
完結散花!!!
總結
以上是生活随笔為你收集整理的洛谷P1550 打井的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kafka Partition重分配流程
- 下一篇: java 文件压缩并设置密码解压