zoukankan      html  css  js  c++  java
  • P1340 兽径管理

    最后一道生成树的绿题,那肯定是切了它呀

    题意解释一下吧,就是每一次加入一条边,在加入之后是否能使这个图连通:可以连通,输出当前的最小路径之和;无法连通,输出-1

    第一反应是裸的最小生成树,每次加一条边就直接跑一次最小生成树,判断是否连通就可以了,那么就诞生了第一份程序,我就不注释了,比较模板(同学的程序)

    #include <bits/stdc++.h>
    using namespace std;
    struct node{
    	int l , r , w;
    };
    node e[6010];
    int n , m , now , tot , ans;
    int fa[210];
    int find(int x){
    	if(fa[x] == x) return x;
    	return fa[x] = find(fa[x]);
    }
    bool cmp(node x , node y){
    	return x.w < y.w;
    }
    int main(){
    	cin >> n >> m;
    	while(m--){
    		tot++;
    		cin >> e[tot].l >> e[tot].r >> e[tot].w;
    		for(int i = 1; i <= n; i++) fa[i] = i;
    		sort(e + 1 , e + tot + 1 ,  cmp);
    		now = 0 , ans = 0;
    		for(int i = 1; i <= tot; i++){
    			if(now == n - 1) break;
    			int x = find(e[i].l) , y = find(e[i].r);
    			if(x == y) continue;
    			now++;
    			ans += e[i].w;
    			fa[x] = y;
    		}
    		if(now != n - 1) cout << -1 << endl;
    		else cout << ans << endl;
    	}
    	return 0;
    }
    
    

    然后就发现T了很多点,只有50分,因为在每一次加入一条新边的时候,我们就需要重新一次快排,而这样的操作就会使时间复杂度相当大,那么我们就考虑如何换一种方法排序

    插入排序,在每一次将边加入集合之前,我们先找出它应该在哪个位置,直接丢进去就好了,这个过程用数组处理会比较麻烦,但是利用STL中的vector的一些函数,就会使得整个程序简洁又方便理解

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    struct node{
    	int x,y,z;
    };
    vector<node>e;
    int tot;
    int f[5000005];
    int find(int x){
    	if(f[x]==x) return x;
    	return f[x]=find(f[x]);
    }
    void merge(int x,int y){
    	f[find(x)]=find(y);
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	while(m--){
    		int x,y,z;
    		int k=0;
    		scanf("%d%d%d",&x,&y,&z);
    		tot++;
    		for(register int i=0;i<tot-1;i++){
    			if(z<e[i].z) break;
    			k++;
    		}//找到一个适合新边的位置 
    		node bz;
    		bz.x=x,bz.y=y,bz.z=z;
    		e.insert(e.begin()+k,bz); //插入进去 
    		if(tot<n-1) puts("-1");
    		else{
    			for(register int i=1;i<=n;i++) f[i]=i;
    			int now=0,ans=0;
    			for(register int i=1;i<=tot;i++){
    				int fx=find(e[i-1].x),fy=find(e[i-1].y);
    				if(fx!=fy){
    					merge(fx,fy);
    					ans+=e[i-1].z;
    					now++;
    				}
    				if(now==n-1) break;
    			}
    			if(now==n-1) printf("%d
    ",ans);
    			else puts("-1");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    C++互斥器:Semaphores
    C++互斥器:Mutex
    内联函数(inline)
    C++显式转换
    线程同步控制
    拷贝构造函数——防篡改
    extern关键字
    虚析构、纯虚析构
    类的友元关系
    char 与 unsigned char的本质区别
  • 原文地址:https://www.cnblogs.com/Poetic-Rain/p/13368540.html
Copyright © 2011-2022 走看看