P4779,萌新刚学OI,求助板子题
查看原帖
P4779,萌新刚学OI,求助板子题
485688
想吃小熊饼干楼主2021/8/21 22:33

rt,样例过了,然鹅爆零。

#include<bits/stdc++.h>
using namespace std;
#define inf 2147483647
int n,m,s,cnt=1;//cnt表示边的编号 
int head[10010];//以顶点i出发的最后一条边的编号 
long long dis[10010];
bool vis[10010];
struct Edge{
    int to;//表示这条边的终点
    int w;//这条边的边权
    int next;//与这条边同一起点的上一条边的编号 
}edge[500010];
struct node{
    int index;long long dist;//index表示点的编号 dist表示从起点到该点当前的最短距离
    //优先队列默认的是大根堆  我们需要的是小根堆 
    //重载运算符
    friend bool operator < (node a,node b){
        return a.dist>b.dist;//从小到大的顺序 
    }   
};
//链式前向星 加边操作 
void add_edge(int u,int v,int w){//u表示起点 v表示终点 w表示边权 
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
priority_queue<node> q;
int main(){
    //dijkstra+堆优化
    cin>>n>>m>>s;
    for(int i=1;i<=m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        add_edge(u,v,w);//构建邻接表 
    }
    for(int i=1;i<=n;i++) dis[i]=inf;
    //memset(dis,0x3f,sizeof(dis));
    dis[s]=0;
    q.push(node{s,0});//起点入队
    while(!q.empty()){
        node x=q.top();
        q.pop();
        int u=x.index;
        if(vis[u]) continue;
        vis[u]=1;//加入s集合 
        for(int j=head[u];j;j=edge[j].next){
            if(dis[edge[j].to]>dis[u]+edge[j].w){
                dis[edge[j].to]=dis[u]+edge[j].w;//松弛 
                q.push(node{edge[j].to,dis[edge[j].to]});//将被更新的点入队 
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<dis[i]<<" ";
    }
    return 0;
} 
2021/8/21 22:33
加载中...