找出知晓秘密的所有专家
作者:互联网
这道题目是一道Dijkstrra的题目。
我们先来回顾一下加边函数
void add(int u,int v,int w) { edge[k].to=v; edge[k].w=w; edge[k].next=head[u]; head[u]=k++; }
这道题目可以用优先队列也可以用手写队列(我要用优先队列)
普通的大小根堆都要有三个参数但我们还可以这样:
struct qnode{ int u,t; bool operator < (const qnode r) const { return t>r.t; } }; priority_queue<qnode> que;
主要说划下滑部分,就是重新定义<号 const 让r始终不变
我们这道题目就用结构体来写吧,用数组也行。
dij函数:
1.初始化que
2.在不为空情况下执行
(一) 取出首点,判断用没用过,用过就continue
(二) 然后将此点使用并将此点的vis值设为1
最后遍历一下每个专家,如果专家知道秘密就输出专家编号-1.
程序:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+20; const int inf = 0x3f; struct Edge{ int to,next,w; }edge[maxn]; int k,head[maxn]; void add(int u,int v,int w) { edge[k].to=v; edge[k].w=w; edge[k].next=head[u]; head[u]=k++; } int n,m,st; int dis[maxn],vis[maxn],isok[maxn]; struct qnode{ int u,t; bool operator < (const qnode r) const { return t>r.t; } }; priority_queue<qnode> que; void dij() { que.push({1,0}); que.push({st,0}); for(int i=1;i<=n;i++) { dis[i]=inf; } dis[1]=dis[st]=0; while(que.size()) { qnode tmp=que.top(); que.pop(); int t=tmp.t; int u=tmp.u; if(vis[u]==1) continue; vis[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int w=edge[i].w; int to=edge[i].to; if(t<=w) { dis[to]=w; que.push({to,dis[to]}); } } } } int main() { cin>>n>>m>>st; memset(head,-1,sizeof head);; for(int i=1;i<=m;i++) { int a,b,c; cin>>a>>b>>c; add(a,b,c); add(b,a,c); } dij(); for(int i=1;i<=n;i++) if(dis[i]!=inf) printf("%d ",i-1); return 0; }
标签:找出,const,int,秘密,head,edge,maxn,que,知晓 来源: https://www.cnblogs.com/wjk53233/p/16388703.html