Description
给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值。求从起点1到点N的最小代价。
起点的代价是离开起点的边的边权。终点的代价是进入终点的边的边权
N<=100000
M<=200000
Input
Output
Sample Input
4 5
1 2 5
1 3 2
2 3 1
2 4 4
3 4 8
Sample Output
12
HINT
Source
一眼能看出是最短路变种..
可是我仅仅会n^2建图T_T
n^2建图就是边转点随便建个新图然后最短路即可了..
这妥妥的TLE啊_ (:зゝ∠)_
这里是Claris的正解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define MAXN 100010
#define MAXM 200010
#define LL long long
#define GET (ch>='0'&&ch<='9')
using namespace std;
int n,m,top,Top,cnt,_top;
int start,end;
const LL MAXINT=1ll<<60;
LL dis[MAXM<<1];
bool vis[MAXM<<1];
struct edge
{
int to,st;
edge *next;
}e[MAXM<<1],*prev[MAXN];
void insert(int u,int ed,int st) {e[++top].to=ed;e[top].st=st;e[top].next=prev[u];prev[u]=&e[top];}
struct Edge
{
int to,w;
Edge *next;
}E[MAXM<<3],*Prev[MAXM<<1];
void Insert(int u,int v,int w) {E[++Top].to=v;E[Top].w=w;E[Top].next=Prev[u];Prev[u]=&E[Top];}
struct S
{
int u,v,w;
bool operator <(const S& a)const {return w<a.w;}
}s[MAXM<<1],sta[MAXM];
void in(int &x)
{
char ch=getchar();x=0;
while (!GET) ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
struct node
{
int x;
LL dis;
bool operator <(const node& a)const {return dis>a.dis;}
};
void dijkstra(int s)
{
priority_queue<node> heap;
for (int i=1;i<=end;i++) dis[i]=MAXINT;dis[s]=0;heap.push((node){s,0});
while (!heap.empty())
{
int x=heap.top().x;heap.pop();
if (vis[x]) continue;vis[x]=1;
for (Edge *i=Prev[x];i;i=i->next)
if (dis[i->to]>dis[x]+i->w) dis[i->to]=dis[x]+i->w,heap.push((node){i->to,dis[i->to]});
}
}
int main()
{
in(n);in(m);int u,v,w;
for (int i=1;i<=m;i++)
{
in(u);in(v);in(w);
s[++cnt]=(S){u,v,w};s[++cnt]=(S){v,u,w};
insert(u,cnt,cnt-1);insert(v,cnt-1,cnt);
}
for (int i=1;i<=n;i++)
{
_top=0;
for (edge *j=prev[i];j;j=j->next) sta[++_top]=(S){j->to,j->st,s[j->to].w};
if (!_top) continue;sort(sta+1,sta+_top+1);
for (int j=1;j<=_top;j++) Insert(sta[j].u,sta[j].v,sta[j].w);
for (int j=1;j<_top;j++) Insert(sta[j].v,sta[j+1].v,sta[j+1].w-sta[j].w),Insert(sta[j+1].v,sta[j].v,0);
}
start=cnt+1;end=start+1;
for (int i=1;i<=cnt;i++)
{
if (s[i].u==1) Insert(start,i,s[i].w);
if (s[i].v==n) Insert(i,end,s[i].w);
}
dijkstra(start);cout<<dis[end]<<endl;
}