题目链接:
https://ac.nowcoder.com/acm/problem/15108
题目很简单,就是个最小生成树问题
kruskal和Prim都可以
因为刚学了dijkstra的堆优化,所以想尝试一波堆优化的Prim算法,算是一种举一反三了吧
Prim算法中,dis数组就是各点离生成树的最短距离,在此题中就是建路花费
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M=110,N=10100;
int head[M],dis[M],cnt;
struct node{
int fr,to,nxt;
ll val;
}e[N<<1];
void add(int u,int v,ll w){
e[++cnt].to=v;
e[cnt].fr=u;
e[cnt].val=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
bool cmp(node a,node b){
return a.val<b.val;
}
int main(){
ll c,cost=0;
int n,m;
cin>>c>>n>>m;
for(int i=1;i<=n;i++)
{
int u,v;
ll w;
cin>>u>>v>>w;
add(u,v,w);
// add(v,u,w);
}
priority_queue<pair<int,int> >q;
memset(dis,0x3f,sizeof dis);
dis[1]=0;
q.push({0,1});
while(!q.empty())
{
int dh=q.top().first; //注意first是距离,不要弄反了
int h=q.top().second;
q.pop();
if(dh+dis[h]) continue;
for(int i=head[h];i;i=e[i].nxt)
{
int t=e[i].to;
if(dis[t]>e[i].val)
{
dis[t]=e[i].val;
q.push({-dis[t],t});
}
}
}
for(int i=1;i<=m;i++) cost+=dis[i];
if(c>=cost) cout<<"Yes";
else cout<<"No";
return 0;
}
注意:不能存反向边,不然当后一个点进入生成树中又会反过来更新前面的点(误把后面的点当作树来更新)