4289: PA2012 Tax
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 182 Solved: 75
[ Submit][ Status][ Discuss]
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
HINT
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#define N 2000000
#define M 400003
#define LL long long
#define inf 1000000000
#define pa pair<long long,int>
using namespace std;
int n,m,tot,tot1,s,t;
int head[M],nxt[M],v1[M],point[N],next[N],v[N],num[N];
LL len[N],c[N],dis[N];
struct data
{
int l,r; LL x;
}a[M];
void add(int x,int y,LL z)
{
tot1++; nxt[tot1]=head[x]; head[x]=tot1; v1[tot1]=y; len[tot1]=z;
tot1++; nxt[tot1]=head[y]; head[y]=tot1; v1[tot1]=y; len[tot1]=z;
}
void build(int x,int y,LL z)
{
tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z;
}
void dijkstra(int s,int t)
{
priority_queue<pa,vector<pa>,greater<pa> > q;
for (int i=0;i<=t;i++)
dis[i]=inf*(LL)(n+1);
dis[s]=0; q.push(make_pair(dis[s],s));
while(!q.empty())
{
int now=q.top().second; q.pop();
for (int i=point[now];i!=-1;i=next[i])
if (dis[now]+c[i]<dis[v[i]])
{
dis[v[i]]=dis[now]+c[i];
q.push(make_pair(dis[v[i]],v[i]));
}
}
}
int cmp(data a,data b)
{
return a.x<b.x;
}
int main()
{
scanf("%d%d",&n,&m);
tot1=-1;
memset(head,-1,sizeof(head));
memset(nxt,-1,sizeof(nxt));
tot=-1;
memset(point,-1,sizeof(point));
memset(next,-1,sizeof(next));
for (int i=1;i<=m;i++)
{
int x,y; LL z; scanf("%d%d%lld\n",&x,&y,&z);
add(x,y,z);
}
for (int i=1;i<=n;i++)
{
int cnt=0;
for (int j=head[i];j!=-1;j=nxt[j])
{
++cnt;
a[cnt].l=j^1;
a[cnt].r=j;
a[cnt].x=len[j];
}
sort(a+1,a+cnt+1,cmp);
for (int j=1;j<=cnt;j++)
{
build(a[j].l,a[j].r,a[j].x);
if (j!=1) build(a[j].r,a[j-1].r,0);
if (j!=cnt) build(a[j].r,a[j+1].r,abs(a[j+1].x-a[j].x));
}
}
s=tot1+1; t=s+1;
for (int i=head[1];i!=-1;i=nxt[i])
build(s,i,len[i]);
for (int i=head[n];i!=-1;i=nxt[i])
build(i,t,0);
dijkstra(s,t);
printf("%lld\n",dis[t]);
}