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;
}