【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\n",ans); return 0; }