#include
using namespace std;
const int maxn=1e5+10;
int rank[maxn],parent[maxn],ans,n,m;//rank用来压缩路径,parent用来存放父节点;
struct person
{
int x;//位置1
int y;//位置2
int v;//两位置的权值
} p[maxn];
bool cmp(person a,person b)
{
return a.vrank[y])parent[y]=x;
else if(rank[x]>n>>m;
clear(n);
for(int i=0; i>p[i].x>>p[i].y>>p[i].v;
sort(p,p+m,cmp);
kuskal();
cout<
Prim算法跟dj算法很像很像,都是一次循环找出一个顶点,然后利用该顶点去扩展其他的待定顶点加入到队列中,鄙人认为这两个算法的不同之处在于prim算法的dis数组的意义在于其他未进入生成树的顶点到生成树的距离,这一点很重要,因为重点在于未进入生成树的点的值对应的不是生成树中的某个点,而是整个树
然后dj算法是着重于dis数组里面已经确地的值,通过这些值去寻找接下来的待定值
#include
#define INF 10000
using namespace std;
constint N = 6;
bool visit[N];
intdist[N] = { 0, };
intgraph[N][N] = { {INF,7,4,INF,INF,INF}, //INF代表两点之间不可达
{7,INF,6,2,INF,4},
{4,6,INF,INF,9,8},
{INF,2,INF,INF,INF,7},
{INF,INF,9,INF,INF,1},
{INF,4,8,7,1,INF}
};
int prim(int cur)
{
intindex = cur;
intsum = 0;
inti = 0;
intj = 0;
cout << index << " ";
memset(visit,false, sizeof(visit));
visit[cur] = true;
for(i = 0; i < N; i++)
dist[i] = graph[cur][i];//初始化,每个与a邻接的点的距离存入dist
for(i = 1; i < N; i++)
{
int minor = INF;
for(j = 0; j < N; j++)
{
if(!visit[j] && dist[j] < minor) //找到未访问的点中,距离当前最小生成树距离最小的点
{
minor = dist[j];
index = j;
}
}
visit[index] = true;
cout << index << " ";
sum += minor;
for(j = 0; j < N; j++)
{//更新一个点index,就从index开始出其他新的dist
if(!visit[j] && graph[index][j]
#include
#include
#include
#include
#include
using namespace std;
//n个顶点m条路
const int maxn=1e3;//m的范围
const int maxm=100+10;//顶点个数
const int INF=0x3f3f3f;
struct node
{
int next,to,val;
} edge[maxn];
int head[maxm],cnt,n,m,dis[maxm],vis[maxm],res;
void add(int x,int y,int val)
{
edge[++cnt].val=val;
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt;
}
void prim(int cur)
{
int res=0;
memset(vis,0,sizeof(vis));
for(int i=1; i<=m; i++)
{
dis[i]=INF;
vis[i]=0;
}
dis[cur]=0;
priority_queue,vector >,greater > > q;
q.push(make_pair(0,cur));
while(!q.empty())
{
int temp=q.top().second;
q.pop();
if(vis[temp])continue;
vis[temp]=1;
res+=dis[temp];
//cout<edge[j].val)
{
dis[edge[j].to]=edge[j].val;
q.push(make_pair(dis[edge[j].to],edge[j].to));
}
}
}
for(int i=1; i<=m; i++)
if(!vis[i])
{
cout<<"?"<>n;
if(n==0)break;
cin>>m;
int u,v,weight;
cnt=1;
for(int i=1; i<=n; i++)
{
scanf("%d%d%d",&u,&v,&weight);
add(u,v,weight);
}
prim(1);
}
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
//n个顶点m条路
const int maxn=1e5;//m的范围
const int maxm=1e5+10;//顶点个数
const int INF=0x3f3f3f;
struct node
{
int next,to,val;
} edge[maxn];
int head[maxm],cnt,n,m,dis[maxm],vis[maxm],res,flag;
void add(int x,int y,int val)
{
edge[cnt].val=val;
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt++;
}
void prim(int cur)
{
int res=0;
for(int i=1; i<=n; i++)
{
dis[i]=INF;
vis[i]=0;
}
for(int i=head[cur]; i; i=edge[i].next)
// dis[edge[i].to]=min(edge[i].val,dis[edge[i].to]);
dis[edge[i].to]=edge[i].val;
// for(int i=1;i<=n;i++)
// printf("i==%d dis[i]==%d\n",i,dis[i]);
dis[cur]=0;
vis[cur]=1;
int j=1;
for( j=1; jedge[i].val)
dis[edge[i].to]=edge[i].val;
}
}
if(j>m;
if(m==0)break;
cin>>n;
int u,v,weight;
cnt=1;
memset(edge,0,sizeof(edge));
memset(head,0,sizeof(head));
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&u,&v,&weight);
add(u,v,weight);
add(v,u,weight);
}
prim(1);
}
return 0;
}
prim算法跟最短路的dj算法最不一样的地方在于
for(int i=head[flag]; i; i=edge[i].next)
{
if(!vis[edge[i].to]&&dis[edge[i].to]>edge[i].val)
dis[edge[i].to]=edge[i].val;
}
dj的是for(int i=head[flag]; i; i=edge[i].next)
{
if(!vis[edge[i].to]&&dis[edge[i].to]>dis[tem]+edge[i].val)
dis[edge[i].to]=edge[i].val+dis[temp];
}
注意这个dis【temp】在prim算法中是没有的
还有要注意重边和有无方向