bzoj 4289: PA2012 Tax

来源:互联网 发布:清与贝加尔湖知乎 编辑:程序博客网 时间:2024/05/29 14:46

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


重新建图跑最短路

把边看成点,每条边(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;}