其他分享
首页 > 其他分享> > 找出知晓秘密的所有专家

找出知晓秘密的所有专家

作者:互联网

 

 这道题目是一道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