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
1 2 5
1 3 2
2 3 1
2 4 4
3 4 8
Sample Output
12
重新建图跑最短路
把边看成点,每条边(x,y)有(x,y)和(y,x)两个点,点之间互相连长度为原长的边
然后对于每个起点x,枚举所有的边(x,t),从小到大排序,每条边向比它大的第一条边连权值为差值的边,再连一条权值为0的反向边
对于以1为起点和n为终点的,新建两个点S,T。S连所有以1为起点的边,所有以n为终点的边连T
然后从S到T跑最短路即可
我的SPFA T掉了,后来改成了Dijstra才跑过去
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct line
{
int s,t;
long long x;
int next,p;
bool operator <(line y) const
{
return x>y.x;
}
}a[1600001],b[500001];
int head[800001];
int edge;
inline void add(int s,int t,long long x)
{
a[edge].next=head[s];
head[s]=edge;
a[edge].s=s;
a[edge].t=t;
a[edge].x=x;
}
inline bool cmp(line x,line y)
{
return x.s<y.s||x.s==y.s&&x.x<y.x;
}/*
long long dis[1600001];
bool v[1600001];
queue<int> Q;
inline long long spfa(int ss,int tt)
{
memset(dis,127/3,sizeof(dis));
memset(v,false,sizeof(v));
Q.push(ss);
v[ss]=true;
dis[ss]=0;
while(!Q.empty())
{
int d=Q.front();
Q.pop();
v[d]=false;
int i;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(dis[d]+a[i].x<dis[t])
{
dis[t]=dis[d]+a[i].x;
if(!v[t])
{
v[t]=true;
Q.push(t);
}
}
}
}
if(dis[tt]==dis[1600000])
return -1;
return dis[tt];
}*/
long long dis[1600001];
bool v[1600001];
priority_queue<pair<long long,int>,vector<pair<long long,int> >,greater<pair<long long,int> > > Q;
inline long long dij(int ss,int tt)
{
memset(dis,127/3,sizeof(dis));
memset(v,false,sizeof(v));
v[ss]=true;
dis[ss]=0;
Q.push(make_pair(dis[ss],ss));
while(!Q.empty())
{
pair<long long,int> xx;
xx=Q.top();
Q.pop();
for(int i=head[xx.second];i!=0;i=a[i].next)
{
int t=a[i].t;
if(dis[xx.second]+a[i].x<dis[t])
{
dis[t]=dis[xx.second]+a[i].x;
Q.push(make_pair(dis[t],t));
}
}
}
return dis[tt];
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=m;i++)
{
scanf("%d%d%lld",&b[i*2-1].s,&b[i*2-1].t,&b[i*2-1].x);
b[i*2-1].p=i*2-1;
b[i*2].s=b[i*2-1].t;
b[i*2].t=b[i*2-1].s;
b[i*2].x=b[i*2-1].x;
b[i*2].p=i*2;
}
for(i=1;i<=m;i++)
{
edge++;
add(i*2-1,i*2,b[i*2-1].x);
edge++;
add(i*2,i*2-1,b[i*2-1].x);
if(b[i*2].s==1)
{
edge++;
add(0,i*2,b[i*2].x);
}
if(b[i*2-1].s==1)
{
edge++;
add(0,i*2-1,b[i*2-1].x);
}
if(b[i*2].t==n)
{
edge++;
add(i*2,2*m+1,b[i*2].x);
}
if(b[i*2-1].t==n)
{
edge++;
add(i*2-1,2*m+1,b[i*2-1].x);
}
}
sort(b+1,b+1+2*m,cmp);
for(i=1;i<=2*m;i++)
{
if(b[i].s==b[i-1].s)
{
edge++;
add(b[i-1].p,b[i].p,b[i].x-b[i-1].x);
edge++;
add(b[i].p,b[i-1].p,0);
}
}
// long long ans=spfa(0,2*m+1);
long long ans=dij(0,2*m+1);
printf("%lld\n",ans);
return 0;
}