• 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;
    }
    
  • 相关阅读:
    【Android】自带Theme
    【网络】SSH
    【Android】录音暂停和继续
    【Android】屏幕翻转(screen orientation change)
    【Android每日一讲】2012.10.31 关于(about)程序信息 Menu功能菜单程序设计
    [Android Samples视频系列之ApiDemos] AppActivityFinish Affinity
    初识移动互联网
    [Android Samples视频系列之ApiDemos] AppActivityHello world
    【Android每日一讲】2012.10.29 控制不同的文字字体 Typeface对象使用
    [Android Samples视频系列之ApiDemos] AppActivityIntentActivityFlags
  • 原文地址:https://www.cnblogs.com/Potrem/p/Luogu_P3366.html
Copyright © 2020-2023  润新知