CCF201812-4数据中心

vector版本的Prim,解决了爆内存的问题,但还是超时。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <iostream>

using namespace std;
struct Node
{
    int dest;
    int cost;
};
 const int INF = 0x3f3f3f3f;
 const int MAXN = 500005;
vector<Node> node[MAXN];
int dis[MAXN];
int vis[MAXN];


int main()
{
   	int n, m,root;//n个点,m条线,源点root 
   	Node temp;
    int i,j,a, b, c;//临时变量 
    while(cin >> n >> m)
    {
		cin>>root;
    	for(i=0; i<=n; i++)
    	{
        	node[i].clear();
    	}
       

        for(i = 0;i < m;++i)
        {
            cin >> a >> b >> c;//a到b路长c 
           
            temp.dest=b;
            temp.cost=c;
            node[a].push_back(temp);
           
            temp.dest=a;
           
           	node[b].push_back(temp);
            
        }
    
    vector<Node>::iterator it;
    memset(vis, 0, sizeof(vis));
    memset(dis, 0x3f, sizeof(dis));
    for(it=node[root].begin(); it!=node[root].end(); it++ )
    {
        dis[it->dest]=it->cost;
    }
    vis[root]=1;
    int pos,mm;
     int maxpath=0;//最小生成树中最大路径 
 
    for(i=1; i<n; i++ )
    {
        mm=INF;
        for(j=1; j<=n; j++)
        {
            if(!vis[j] && dis[j]<mm )
            {
                mm=dis[j];
                pos=j;
            }
        }
        if(maxpath<mm)
        maxpath=mm;
        vis[pos]=1;
        for(it=node[pos].begin(); it!=node[pos].end(); it++ )
        {
            if( !vis[it->dest] && it->cost <dis[it->dest] )
            {
                dis[it->dest]=it->cost;
            }
        }
    }
    printf("%d\n", maxpath );
}
    return 0;
}

Kruskal解决超时问题,因为这个题是稀疏图 

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>
using namespace std;
const int MAXV = 500001;
int n, m;//顶点数和边数
int cnt;//记录添加的边数
int father[MAXV];
struct adj 
{
    int u,v;
    int value;
}Adj;//定义一个临时变量

//算法排序比较函数
bool cmp(adj x,adj y)
{
    return x.value < y.value;
}

vector<adj> adjs;//边集

//并查集搜索函数
//路径压缩,找父节点
int fatherfind(int x) 
{
    if(x!=father[x])
        father[x]=fatherfind(father[x]);
    return father[x];
}

/*
非递归
int fatherfind(int x) 
{
	int r=x;
	while(r!=father[r])
	  r=father[r];
	//路径压缩 
	while(x!=r)
	{
		int i=father[x];
		father[x]=r;
		x=i;
	}
	return r;	   
}
*/

int kruskal() 
{
    int maxadj = 0;//需要找到的最大边,即为Tmax
    //初始化并查集
    for (int i = 1; i <= n; i++) 
    {
        father[i] = i;
    }
    //排序
    sort(adjs.begin(), adjs.end(), cmp);
    vector<adj>::iterator it;
    for ( it= adjs.begin(); it != adjs.end(); it++) 
    {
        int faU = fatherfind(it->u);
        int faV = fatherfind(it->v);
        if (faU != faV) //如果边的两点不是在同一个集合
        {		
	        father[faU] = faV;	//合并两个子集合
	        if(maxadj<it->value) 
	        {
	        	 maxadj=it->value;//找到最小生成树中的最大边
             }

             cnt++;
             if(cnt==n-1)    
                break;    //最小生成树的边长是n-1
        }

    } 
    return maxadj;
}
int main() 
{
    int root;
    cin >> n >> m>>root;
    for (int i = 1; i <=m; i++) 
    {
     cin >> Adj.u >> Adj.v >> Adj.value;
     adjs.push_back(Adj);
 }
 cnt=0;
 cout << kruskal();
 return 0;
}

猜你喜欢

转载自blog.csdn.net/william_munch/article/details/88582112