zoukankan      html  css  js  c++  java
  • 数据结构-造树计划-最小生成树

    最小生成树

    思路

    • 沿某一点绕一圈,遇到最小的点往路径最小的点走

    • 并用p[]数组来记录该点的父结点

      p[v]=u(表示v的父节点是u),方便求出路径和sum+=G[i][p[i]]

    • 如果说p[v]=提前设定好的值,也就是说它没有被改变,那么要么这个点是出发点,要么这个点是被“隔离”的。

    • 加强理解的手段,用color数组,取三个值分别表示已经被用(BLACK),要被用(GRAY)和还没有探索到(WHITE)

    • 确定新起点(注意原起点打通了与新起点的通道(使得这些点变成了灰色(缓冲点)),d[v]=d[u][v]

    • 注意:可能还要考虑重边和自环

    AC代码P3366 【模板】最小生成树

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    static const int MAX=5005;
    static const int WHITE=0;//表示未用过的点 
    static const int GREY=1;//表示待用的点 
    static const int BLACK=2;//表示用过的点 
    static const int INFTY=999999;
    int G[MAX][MAX];
    int p[MAX];
    int color[MAX];
    int d[MAX];
    int num,n;
    void prim()
    {
    	//初始化
    	for(int i=1;i<=num;i++)
    	{
    		p[i]=-1;
    	    color[i]=WHITE;	
    	    d[i]=INFTY; 
    	} 
    	
    	d[1]=0;
    	
    	
    	while(1)
    	{
    		int u=-1;
    		int minv=INFTY;
    		
    	//	cout<<2<<endl;
    		for(int i=1;i<=num;i++)
    		{	
    		  //  cout<<3<<endl;
    			if(d[i]<minv&&color[i]!=BLACK)
    			{
    	//			cout<<4<<endl;
    				
    				u=i;
    	//			cout<<u<<endl;
    				minv=d[i];
    			}
    		}
    		
    		if(u==-1)break;
    		
    		color[u]=BLACK;
    		
    		for(int v=1;v<=num;v++)
    		{
    			if(color[v]!=BLACK&&d[v]>G[u][v]&&u!=v)
    			{
    				color[v]=GREY;
    				d[v]=G[u][v];
    				p[v]=u;
    			}
    		}
    	}
    	
    	int total=0;
    	int flag=1; 
    	for(int v=2;v<=num;v++)
    	{
    	//	cout<<6<<endl;
    		if(p[v]==-1)
    		{
    			flag=0;
    			cout<<"orz";
    			break;
    		}
    		total+=G[v][p[v]];
    	//	cout<<p[v]<<"     "<<G[v][p[v]]<<"     "<<total<<endl;
    	}
    	if(flag)cout<<total;
    }
    int main()
    {
    	cin>>num>>n;
    	
    	for(int i=1;i<=num;i++)
    	{
    		for(int j=1;j<=num;j++)
    		{
    			G[i][j]=INFTY;
    			G[j][i]=INFTY;
    		}
    	}
    	
    	for(int i=1;i<=n;i++)
    	{
    		int s,t,e;
    		cin>>s>>t>>e;
    		if(G[s][t]>=e)
    		{
    		G[s][t]=e;
    		G[t][s]=e;
    		}
    		//cout<<G[s][t];
    	}
    	prim();
    	
    	return 0;
    }
    

    其他

    距离无穷大

    static const int INFTY =(1<<21);

    参考资料

    1. 挑战程序设计竞赛

    2. zjl大佬

    3. 洛谷链接

  • 相关阅读:
    Binary Tree Zigzag Level Order Traversal
    Binary Tree Level Order Traversal
    Symmetric Tree
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Triangle
    Populating Next Right Pointers in Each Node II
    Pascal's Triangle II
    Pascal's Triangle
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/14532122.html
Copyright © 2011-2022 走看看