算法思想:从任意一点出发,记录点的最小权值,每一次将最小边的结点标记一下,直到所有的点都被加到树里面。优先队列将边按从小到大的顺序排列,队首为最小的边。
板子题:HUD-1863
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1e5;
int head[N];
int cnt=0;
struct node{
int to,next,val;
}mp[N];
struct nod{ //优先队列排序;
int pos,val;
bool friend operator <(nod a, nod b)
{
return a.val>b.val;
}
};
void add(int x, int y, int val) //链式向前星建边;
{
mp[cnt].to=y;
mp[cnt].val=val;
mp[cnt].next=head[x];
head[x]=cnt++;
}
int prime(int m)
{
bool p[200];
priority_queue<nod >q;
memset(p,false,sizeof(p)); //初始化标记数组;
int i,to,val,ans=0,tot=0;
q.push(nod{1,0}); //压入起点值;
while(!q.empty()){
nod are=q.top();
q.pop();
int u=are.pos;
if(p[u]) continue;
p[u]=true;
ans+=are.val; //权值加入答案;
++tot; //记录个数;
for(i=head[u];~i;i=mp[i].next){
to=mp[i].to;
val=mp[i].val;
q.push(nod{to,val});
}
}
if(tot==m) return ans;
return 0;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF&&n){
int x,y,val;
cnt=0;
memset(head,-1,sizeof(head));
for(int i=0;i<n;++i){
scanf("%d%d%d",&x,&y,&val);
add(x,y,val);
add(y,x,val);
}
int ans=prime(m);
if(ans){
printf("%d\n",ans);
}
else{
printf("?\n");
}
}
return 0;
}
算法思想:
1.先对所有的边排序;
2.依次从小到大将边加入到树中,在维护结点的时候运用并查集判断是否已经在相同集合中,若不再相同结点中则将边加入到树中;
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1e3;
int pre[N];
struct node{
int x,y,val;
}mp[N*10];
bool cpu(node a, node b) //对边排序;
{
return a.val<b.val;
}
int find(int x) //并查集查找根节点+路径压缩;
{
if(pre[x]==x) return pre[x];
return pre[x]=find(pre[x]);
}
int kruskal(int n, int m)
{
int tot=0,ans=0,fx,fy,x,y,val;
for(int i=0;i<n;++i){
x=mp[i].x;
y=mp[i].y;
val=mp[i].val;
fx=find(x);
fy=find(y);
if(tot==m-1) break;
if(fx!=fy){
pre[fx]=fy;
ans+=val;
++tot;
}
}
if(tot==m-1 ) return ans;
return 0;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF&&n){
for(int i=0;i<n;++i) {
scanf("%d%d%d",&mp[i].x,&mp[i].y,&mp[i].val);
}
sort(mp,mp+n,cpu);
for(int i=1;i<=m;++i) pre[i]=i; //并查集初始化前导节点数组;
int ans=kruskal(n,m);
if(ans) printf("%d\n",ans);
else printf("?\n");
}
return 0;
}