zoukankan      html  css  js  c++  java
  • P3366 【模板】最小生成树


    P3366 【模板】最小生成树



    时间限制 1.00s
    内存限制 125.00MB


    题目描述


    如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz


    输入格式


    第一行包含两个整数\(N,M\),表示该图共有\(N\)个结点和\(M\)条无向边。

    接下来\(M\)行每行包含三个整数\(X_i,Y_i,Z_i\),表示有一条长度为\(Z_i\)的无向边连接结点 \(X_i,Y_i\)


    输出格式


    如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz


    输入输出样例


    输入 #1

    4 5
    1 2 2
    1 3 2
    1 4 3
    2 3 4
    3 4 3
    

    输入 #2

    7
    

    说明/提示


    数据规模:

    对于\(20\%\)的数据,\(N\le 5\)\(M\le 20\)

    对于\(40\%\)的数据,\(N\le 50\)\(M\le 2500\)

    对于\(70\%\)的数据,\(N\le 500\)\(M\le 10^4\)

    对于\(100\%\)的数据:\(1\le N\le 5000\)\(1\le M\le 2\times 10^5\)

    样例解释:

    所以最小生成树的总边权为 2+2+3=72+2+3=72+2+3=7。

    所以最小生成树的总边权为\(2+2+3=7\)



    推荐Nemlit最小生成树算法


    Kruskal算法


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e5+5;
    int f[N],ans,cnt;
    bool tmp;
    struct edge{
    	int x,y,z;
    }e[N];
    bool cmp(edge a,edge b){
    	return a.z<b.z;
    }
    int find(int x){ return f[x]==x ? x : f[x]=find(f[x]); }
    int main(){
    	int n,m;
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;++i) f[i]=i;
    	for(int i=1;i<=m;++i) scanf("%d %d %d",&e[i].x,&e[i].y,&e[i].z);
    	sort(e+1,e+1+m,cmp);
    	for(int i=1;i<=m;++i){
    		int fx=find(e[i].x),fy=find(e[i].y);
    		if(fx==fy) continue;
    		f[fy]=fx;
    		ans+=e[i].z;
    		++cnt;
    		if(cnt==n-1){
                tmp=1;
                break;
            }
    	}
    	if(tmp) printf("%d",ans);
        else puts("orz");
    	return 0;
    }
    

    Prim算法


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    const int N=2e5+5;
    int cnt,ans,dis[N];
    vector<int>e[N],w[N];
    bool vis[N];
    struct node{
    	int u,w;
    };
    bool operator < (node x,node y){
    	return x.w>y.w;
    }
    priority_queue<node>q;
    void prim(int n){
    	memset(dis,0x3f,sizeof(dis));
    	dis[1]=0; q.push(node{1,0}); 
    	while(!q.empty()&&cnt<n){
    		int u=q.top().u,W=q.top().w; q.pop();
    		if(vis[u]) continue; vis[u]=1;
    		ans+=W;
    		++cnt; 
    		for(int v,W,i=0;i<e[u].size();++i){
    			v=e[u][i]; W=w[u][i];
    			if(W<dis[v]){
    				dis[v]=W;
    				q.push(node{v,W});
    			}
    		}
    	}
    }
    int main(){
    	int n,m;
    	scanf("%d %d",&n,&m);
    	while(m--){
    		int x,y,z;
    		scanf("%d %d %d",&x,&y,&z);
    		e[x].push_back(y);
    		w[x].push_back(z);
    		e[y].push_back(x);
    		w[y].push_back(z);
    	}
    	prim(n);
    	if(cnt==n) printf("%d",ans);
    	else puts("orz");
    	return 0;
    }
    
  • 相关阅读:
    NTC温度检测程序(转)
    基于GPS的经纬度、方位角、距离、航向计算及基于单目视觉的距离计算!
    GPS速度和航向计算(转)
    NOR、 NAND、Raw Flash和 Managed Flash的区别(转)
    FreeModbus V1.6 主机使用说明(转)
    只要单片机具有真正唯一ID,就可以让加密坚不可摧(转)
    Java 给Word添加数字签名
    Java 获取Word中指定图片的坐标位置
    C#/VB.NET 自定义PPT动画路径
    在线编辑Excel——插入图表
  • 原文地址:https://www.cnblogs.com/Potrem/p/Luogu_P3366.html
Copyright © 2011-2022 走看看