zoukankan      html  css  js  c++  java
  • 14-道路建设(最小生成树)

    链接:https://www.nowcoder.net/acm/contest/76/B
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 65536K,其他语言131072K
    64bit IO Format: %lld

    题目描述

    随着如今社会的不断变化,交通问题也变得越来越重要,所以市长决定建设一些公路来方便各个城市之间的贸易和交易。虽然市长的想法很好,但是他也遇到了一般人也经常头疼的问题,那就是手头的经费有限……在规划过程中,设计师们已经预算出部分城市之间建设公路的经费需求。现在市长想知道,它能不能将他的m个城市在有限的经费内实现公路交通。如果可以的话,输出Yes,否则输出No(两个城市不一定要直接的公路相连,间接公路到达也可以。)

    输入描述:

    测试输入包含多条测试数据
    每个测试数据的第1行分别给出可用的经费c(<1000000),道路数目n(n<10000),以及城市数目m(<100)。
    接下来的n行给出建立公路的成本信息,每行给出三个整数,分别是相连的两个城市v1、v2(0<v1,v2<=m)以及建设公路所需的成本h(h<100)。

    输出描述:

    对每个测试用例,输出Yes或No。
    示例1

    输入

    20 10 5
    1 2 6
    1 3 3
    1 4 4
    1 5 5
    2 3 7
    2 4 7
    2 5 8
    3 4 6
    3 5 9
    4 5 2

    输出

    Yes
    示例2

    输入

    10 2 2
    1 2 5
    1 2 15

    输出

    Yes

    备注:

    两个城市之间可能存在多条线路

    Kruskal算法:
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef struct Edge{
    	int x;
    	int y;
    	int w;
    }Edge;
    Edge edge[10005];
    int n, m;  //n道路数,m城市数 
    int f[105];
    bool cmp(Edge a, Edge b){
    	return a.w < b.w;
    }  
    int find(int x){
    	if(f[x] == -1) 
    		return x;
    	else{
    		return find(f[x]);
    	}
    }
    /*
    压缩一下的并查集 
    int find(int x){ 
        int root = x; 
        while(root != par[root]) root = par[root]; 
        while(x != root){ 
            int t = par[x]; 
            par[x] = root; 
            x = t; 
        } 
        return root; 
    } 
       
    void unite(int x, int y){ 
        x = find(x); 
        y = find(y); 
        if(Rank[x] < Rank[y]){ 
            par[x] = y; 
        } 
        else{ 
            par[y] = x; 
            if(Rank[x] == Rank[y]) Rank[x]++; 
        } 
    }
    */ 
    
    int Kruskal(){
    	int ans = 0, cnt = 0;
    	sort(edge, edge + n, cmp);
    	for(int i = 0; i < n; i++){
    		int x, y, w;
    		x = edge[i].x;
    		y = edge[i].y;
    		w = edge[i].w;
    		if(find(x) != find(y)){
    			ans += w;
    			f[x] = y; //unite(x,y); 
    			cnt++;
    		}
    		if(cnt == m - 1) //m个城市只需 m - 1条道路就可以了 
    			break;
    	}
    	if(cnt < m - 1){
    		return -1;
    	}
    	return ans;
    }
    int main(){
    	int cost, x, y, w;
    	while(scanf("%d%d%d", &cost, &n, &m) == 3){
    		memset(edge, 0, sizeof(edge));
    		memset(f, -1, sizeof(f));
    		for(int i = 0; i < n; i++){
    			scanf("%d%d%d", &x, &y, &w);
    			edge[i].x = x;
    			edge[i].y = y;
    			edge[i].w = w;
    		}
    		int ans = Kruskal();
    		if(ans <= cost){
    			printf("Yes
    ");
    		}
    		else{
    			printf("No
    ");
    		}
    	}
    	return 0;
    }
    
    
    

    Prim算法:(超内存)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define MAXN 10005
    bool visit[MAXN]; 		//标记数字是否放入一个集合 
    int lowc[MAXN];   		//维护的最低代价数组	
    int cost[MAXN][MAXN];   //边的的权值 
    
    int Prim(int n){
    	int ans = 0;
    	visit[1] = true;
    	for(int i = 2; i <= n; i++){
    		lowc[i] = cost[1][i];
    	}
    	for(int i = 1; i < n; i++){  //将剩余的n-1个点放入visit  
    		int minc = INF;
    		int p = 0;
    		for(int j = 2; j <= n; j++){  //查找一个没有放入visit的且权值最小的顶点 
    			if(!visit[j] && minc > lowc[j]){
    				minc = lowc[j]; 
    				p = j;	
    			}
    		}
    		if(minc == INF) //这是一个不连通图,所以无最小生成树 
    			return -1;
    		ans += minc;
    		visit[p] = true;
    		for(int i = 2; i <= n; i++){ //更新维护顶点到visit集合的最小消耗 
    			if(lowc[i] > cost[p][i]){
    				lowc[i] = cost[p][i];
    			}
    		}
    	}
    	return ans;
    }
    int main(){
    	int n, m; //顶点,边数 
    	int allm = 0;
    	while(scanf("%d%d%d", &allm, &n, &m) == 3){
    		memset(cost, INF, sizeof(cost));
    		int u, v, w;
    		for(int i = 1; i <= m; i++){
    			scanf("%d%d%d", &u, &v, &w);
    			if(cost[u][v] > w){
    				cost[u][v] = w;
    				cost[v][u] = w;	
    			}
    		}
    		int ans = Prim(n);
    //		cout << ans << "xiaofei" <<  endl;
    		if(allm >= ans){
    			printf("Yes
    ");
    		}
    		else{
    			printf("No
    ");
    		}
    	}
    	return 0;
    }
     
    

      

  • 相关阅读:
    day 26 python2和python3的区别 模块logging 的高级版,collections 模块,random模块
    常用模块:time,os,sys,rondom
    模块 hashlib(算法) configparser(配置) logging(日志)
    序列化,json pickle,shelve
    面向对象的封装,多态,单例模式
    属性,类方法,静态方法,反射
    面向对象的接口类 以及鸭子类型
    面向对象的继承
    面向对象的介绍
    reset internet explorer settings with registry
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/8442898.html
Copyright © 2011-2022 走看看