zoukankan      html  css  js  c++  java
  • BZOJ 1601 [Usaco2008 Oct]灌水

    1601: [Usaco2008 Oct]灌水

    Time Limit: 5 Sec  Memory Limit: 162 MB

    Description

    Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记。把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库。 建造一个水库需要花费wi(1<=wi<=100000),连接两块土地需要花费Pij(1<=pij<=100000,pij=pji,pii=0). 计算Farmer John所需的最少代价。

    Input

    *第一行:一个数n

    *第二行到第n+1行:第i+1行含有一个数wi

    *第n+2行到第2n+1行:第n+1+i行有n个被空格分开的数,第j个数代表pij。

    Output

    *第一行:一个单独的数代表最小代价.

    Sample Input

    4
    5
    4
    4
    3
    0 2 2 2
    2 0 3 3
    2 3 0 4
    2 3 4 0

    Sample Output

    9


    输出详解:

    Farmer John在第四块土地上建立水库,然后把其他的都连向那一个,这样就要花费3+2+2+2=9

    这道题,一开始以为是贪心脑补了半天,竟然是最小生成树。我表示再不独立思考我就要跪了!最小生成树就很好想了,虚拟一个点连所有的水库,然后田地之间的边相互连,这样一遍最小生成树就可以求得最小答案了!

    代码:

    /*Author:WNJXYK*/
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<set>
    using namespace std;
    
    #define LL long long
    
    inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
    inline void swap(LL &x,LL &y){LL tmp=x;x=y;y=tmp;}
    inline int remin(int a,int b){if (a<b) return a;return b;}
    inline int remax(int a,int b){if (a>b) return a;return b;}
    inline LL remin(LL a,LL b){if (a<b) return a;return b;}
    inline LL remax(LL a,LL b){if (a>b) return a;return b;}
    
    int Father[500];
    inline void initFather(int n){
    	for (int i=0;i<=n;i++) Father[i]=i;
    }
    inline int getFather(int x){
    	return Father[x]=Father[x]==x?x:getFather(Father[x]);
    }
    inline void mergeFather(int x,int y){
    	int fx=getFather(x),fy=getFather(y);
    	if (fx<fy){
    		Father[fy]=Father[fx];
    	}else{
    		Father[fx]=Father[fy];
    	}
    }
    
    struct Edge{
    	int u,v,value;
    	Edge(){}
    	Edge(int x,int y,int z){u=x;v=y;value=z;}
    };
    Edge e[50000];
    int nume=0;
    inline void addEdge(int x,int y,int cost){
    	e[++nume]=Edge(x,y,cost);
    }
    
    
    inline bool cmp(Edge a,Edge b){
    	if (a.value<b.value) return true;
    	return false;
    }
    
    int n;
    int cnt;
    int Ans;
    int main(){
    	scanf("%d",&n);
    	initFather(n);
    	cnt=n+1;
    	Ans=0;
    	for (int i=1;i<=n;i++){
    		int tmp;
    		scanf("%d",&tmp);
    		addEdge(0,i,tmp);
    	}
    	for (int i=1;i<=n;i++){
    		for (int j=1;j<=n;j++){
    			int tmp;
    			scanf("%d",&tmp);
    			if (j>i) addEdge(i,j,tmp);
    		}
    	}
    	sort(e+1,e+nume+1,cmp);
    	for (int i=1;i<=nume;i++){
    		int x=e[i].u,y=e[i].v,c=e[i].value;
    		if (getFather(x)!=getFather(y)){
    			cnt--;
    			Ans+=c;
    			mergeFather(x,y);
    		}
    		if (cnt==1) break;
    	}
    	printf("%d
    ",Ans);
    	return 0;
    }
    


  • 相关阅读:
    后台取得非服务器控件的一种方法(Request.Form.GetKey(i))
    扩展jQuery键盘事件的几个基本方法(练习jQuery插件扩展)
    Javascript得到CheckBoxList的Value
    sql server的count(小技巧)
    oracle数据库约束条件删除、取消、启用
    iis7.0修改网站端口
    session模式和web园
    理解Session State模式+ASP.NET SESSION丢失FAQ (转)
    Gridview中生成的属性rules="all",在Firefox出现内线框解决办法
    一个类windows系统的效果图
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4063932.html
Copyright © 2011-2022 走看看