給出一個N個點M條邊的無向圖,通過一個點的代價是進入和離開這個點的兩條邊的邊權的較大值,求從起點1到點N的最小代價。起點的代價是離開起點的邊的邊權,終點的代價是進入終點的邊的邊權
N<=100000
M<=200000
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cstdlib> #define REP(i,k,n) for(int i=k;i<=n;i++) #define in(a) a=read() #define MAXN 400040 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } int n,m; int S,T; int total,head[MAXN],to[MAXN*2],nxt[MAXN*2],val[MAXN*2]; int Total,Head[2000000],To[2000000],Nxt[2000000],Val[2000000]; int vis[400010]; long long dis[400010]; struct edge{ int id,va; }st[MAXN*2]; struct node{ int a; long long b; bool operator <(const node &x)const{ return b>x.b; } }; priority_queue<node> Q; inline int change(int x){ if(x%2==1) return x+1; return x-1; } inline void adl(int a,int b,int c){ total++; to[total]=b; val[total]=c; nxt[total]=head[a]; head[a]=total; return ; } inline void Adl(int a,int b,int c){ Total++; To[Total]=b; Val[Total]=c; Nxt[Total]=Head[a]; Head[a]=Total; return ; } inline bool cmp(edge a,edge b){ return a.va<b.va; } inline void solve(int u){ int cnt=0; for(int e=head[u];e;e=nxt[e]) st[++cnt].id=e,st[cnt].va=val[e]; sort(st+1,st+cnt+1,cmp);//對於u的全部出邊排序 REP(i,1,cnt-1) Adl(st[i].id,st[i+1].id,st[i+1].va-st[i].va),Adl(st[i+1].id,st[i].id,0);//連查分邊 for(int e=head[u];e;e=nxt[e]) Adl(change(e),e,val[e]);//每一條出邊連向所對入邊 return ; } inline long long Dijkstra(){ memset(dis,0x7f,sizeof(dis)); dis[S]=0; node p; p.a=S,p.b=0; Q.push(p); while(!Q.empty()){ int u=Q.top().a;Q.pop(); if(vis[u]) continue; vis[u]=1; for(int e=Head[u];e;e=Nxt[e]) if(dis[To[e]]>dis[u]+Val[e]){ dis[To[e]]=dis[u]+Val[e]; node q; q.a=To[e],q.b=dis[To[e]]; Q.push(q); } } return dis[T]; } int main(){ in(n),in(m); int a,b,c; REP(i,1,m) in(a),in(b),in(c),adl(a,b,c),adl(b,a,c); S=0,T=total+1; for(int e=head[1];e;e=nxt[e]) Adl(S,e,val[e]);//處理源點 for(int e=head[n];e;e=nxt[e]) Adl(change(e),T,val[e]);//處理匯點 for(int i=1;i<=n;i++) solve(i); printf("%d",Dijkstra()); return 0; } /* 4 5 1 2 5 1 3 2 2 3 1 2 4 4 3 4 8 */