zoukankan      html  css  js  c++  java
  • (step6.1.4)hdu 1102(Constructing Roads——最小生成树)

    题目大意:输入一个整数n,表示村庄的数目。在接下来的n行中,每行有n列,表示村庄i到村庄 j 的距离。(下面会结合样例说明)。接着,输入一个整数q,表示已经有q条路修好。

    在接下来的q行中,会给出修好的路的起始村庄和结束村庄。。

    输入样例说明如下:



    解题思路:最小生成树(kruscal算法)

    1)以前的题会直接给村庄编号以及村庄距离。而这道题,这是给出村庄的距离矩阵。村庄的编号信息蕴含在

    矩阵中。这时候的读取方法为:

    for(i = 1 ; i <= n ; ++i){
    			for(j = i + 1 ; j <= n ; ++j){
    				e[count].begin = i;
    				e[count].end = j;
    				e[count].weight = map[i][j];
    				count++;
    			}
    		}


    2)点的起始编号与变得起始编号没有必然的联系。即点可以从1开始计数,而边则从0开始计数。

    for( i = 1 ; i < maxn ; ++i){
    		father[i] = i;
    	}
    
    	for( i = 0 ; i < count ; ++i){
    		int fx = find(e[i].begin);
    		int fy = find(e[i].end);
    
    		if(fx != fy){
    			father[fx] = fy;
    			sum += e[i].weight;
    		}
    	}


    3)已修的路,令weight为0即可。


    代码如下:

    /*
     * 1102_1.cpp
     *
     *  Created on: 2013年8月26日
     *      Author: Administrator
     */
    
    
    #include <iostream>
    
    using namespace std;
    
    struct edge{
    	int begin;
    	int end;
    	int weight;
    };
    
    const int maxn = 6000;
    int father[maxn];
    edge e[maxn*maxn];
    
    int find(int x){
    	if( x == father[x]){
    		return x;
    	}
    
    	father[x] = find(father[x]);
    	return father[x];
    }
    
    int kruscal(int count){
    	int i;
    	int sum = 0;
    
    	for( i = 1 ; i < maxn ; ++i){
    		father[i] = i;
    	}
    
    	for( i = 0 ; i < count ; ++i){
    		int fx = find(e[i].begin);
    		int fy = find(e[i].end);
    
    		if(fx != fy){
    			father[fx] = fy;
    			sum += e[i].weight;
    		}
    	}
    
    	return sum;
    }
    
    bool compare(const edge& a , const edge& b){
    	return a.weight < b.weight;
    }
    
    int main(){
    	int n;
    	while(scanf("%d",&n)!=EOF){
    		int i,j;
    		int map[n+1][n+1];
    		for( i = 1 ; i <= n ; ++i){
    			for( j =  1 ; j <= n ; ++j){
    				scanf("%d",&map[i][j]);
    			}
    		}
    		int q;
    		scanf("%d",&q);
    		for( i = 1 ; i <= q ; ++i){
    			int a ,b;
    			scanf("%d%d",&a,&b);
    			map[a][b] = 0;
    		}
    		int count = 0;
    		for(i = 1 ; i <= n ; ++i){
    			for(j = i + 1 ; j <= n ; ++j){
    				e[count].begin = i;
    				e[count].end = j;
    				e[count].weight = map[i][j];
    				count++;
    			}
    		}
    
    		sort(e, e + count , compare);
    
    		int sum = kruscal(count);
    
    		printf("%d
    ",sum);
    
    	}
    }
    




  • 相关阅读:
    Socket编程实现客户端与服务器一对一聊天
    HttpClient获取页面信息与Jsoup封装获取
    代码推送
    re正则
    MySQL 的主从复制
    关于前后端的缓存
    session/cookie/token
    如何保证缓存(redis)与数据库(MySQL)的一致性
    进程与线程(程序与任务)
    QA/QC
  • 原文地址:https://www.cnblogs.com/riskyer/p/3283330.html
Copyright © 2011-2022 走看看