【bzoj4283】魔法少女伊莉雅

似乎是用最短路树随意判一下就好了。

#include<bits/stdc++.h>
#define maxn 100005
#define maxm 500005
#define INF 0x7f7f7f7f

using namespace std;

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

struct scsc{
    int next,to,from,w;
}edge[maxm<<1],_edge[maxm<<1];

int n,m,Len,head[maxn],d1[maxn],d2[maxn],flag[maxm<<1];

struct node{
    int x,d;
    node(int x,int d):x(x),d(d){};
    node(){};
    bool operator < (const node &a)const{
        if(d==a.d)return x<a.x;
        return d>a.d;
    }
};

void addedge(int u,int v,int w){
    edge[++Len].to=v;edge[Len].from=u;edge[Len].w=w;edge[Len].next=head[u];head[u]=Len;
    edge[++Len].to=u;edge[Len].from=v;edge[Len].w=w;edge[Len].next=head[v];head[v]=Len;
}

void dijkstra(int s,int d[]){
    priority_queue<node>Q;
    for(int i=1;i<=n;++i)d[i]=INF;
    Q.push(node(s,0));d[s]=0;
    while(!Q.empty()){
        int u=Q.top().x;Q.pop();
        for(int i=head[u];i;i=edge[i].next){
            int v=edge[i].to;
            if(d[v]>d[u]+edge[i].w){
                d[v]=d[u]+edge[i].w;
                Q.push(node(v,d[v]));
            }
        }
    }
}

int _Len,_head[maxn],fa[maxn];

void _addedge(int u,int v){
    _edge[++_Len].to=v;_edge[_Len].next=_head[u];_head[u]=_Len;
}

void dfs(int u){
    for(int i=_head[u];i;i=_edge[i].next){
        int v=_edge[i].to;
        if(d1[v]+d2[v]!=d1[n])fa[v]=fa[u];else fa[v]=v;
        dfs(v);
    }
}

int main(){
    n=read();m=read();int f1,f2,f3;
    for(int i=1;i<=m;++i){
        f1=read();f2=read();f3=read();
        addedge(f1,f2,f3);
    }
    dijkstra(1,d1);dijkstra(n,d2);
    for(int u=1;u<=n;++u){
        for(int i=head[u];i;i=edge[i].next){
            int v=edge[i].to;
            if(d2[u]==d2[v]+edge[i].w){
                flag[i]=1;
                _addedge(v,u);
                break;
            }
        }
    }
    fa[n]=n;dfs(n);int ans=INF;
    for(int i=1;i<=Len;++i)if(!flag[i]){
        int u=edge[i].from,v=edge[i].to,w=edge[i].w;
        if(d1[u]<=d1[v]&&fa[u]!=fa[v]&&d1[u]+w+d2[v]!=d1[n])ans=min(ans,d1[u]+w+d2[v]);
    }
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/illya/p/7565281.html