free牛客暑假多校训练第四场 J(分层图求最短路板子)

题目链接:
https://ac.nowcoder.com/acm/contest/884/J

题目大意:

给你一个n个点m条边的图。允许一开始条边让其边权变为0,问最短路长度。

解题思路:

分层图求最短路板子

AC代码:

#include 
#define ll long long
using namespace std;
const int maxn = 1e3+10;
const int inf = 0x3f3f3f3f;
int dis[maxn][maxn];
int vis[maxn][maxn];
int head[maxn];
int n,m,k;
int cnt = 0;
struct node{
    int to;
    int w;
    int next;
}side[maxn*2];
struct Node{
    int x,y;
    int d;
    Node(int x,int y,int d):x(x),y(y),d(d){}
    Node(){}
    bool operator <(const Node &t)const {
        return d>t.d;
    }
};
priority_queue<Node> q;
void add(int x,int y,int w){
    side[cnt].to = y;
    side[cnt].w = w;
    side[cnt].next = head[x];
    head[x] = cnt++;
}
void init(){
    memset(head,-1,sizeof(head));
    cnt = 0;
}
int Dijkstra(int s,int e){
    memset(dis,inf,sizeof(dis));
    dis[s][0] = 0;
    q.push(Node(s,0,0));
    while(q.size()){
        int x = q.top().x;
        int y = q.top().y;
        q.pop();
        if(vis[x][y]) continue;
        vis[x][y] = 1;
        for(int i=head[x];i!=-1;i=side[i].next){
            int to = side[i].to;
            if(dis[to][y]>dis[x][y]+side[i].w&&!vis[to][y]){
                dis[to][y] = dis[x][y]+side[i].w;
                q.push(Node(to,y,dis[to][y]));
            }
            if(y+1<=k&&dis[to][y+1]>dis[x][y]&&!vis[to][y+1]){
                dis[to][y+1]=dis[x][y];
                q.push(Node(to,y+1,dis[to][y+1]));
            }
        }
    }
    return dis[e][k];
}
int main(){
    int s,t;
    scanf("%d%d%d%d%d",&n,&m,&s,&t,&k);
    init();
    int u,v,w;
    while(m--){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }
    cout<<Dijkstra(s,t)<<endl;
    return 0;
}

你可能感兴趣的:(图论,最短路问题)