[bzoj4289] PA2012 Tax
暴力都会吧,然后愉快的炸空间。
我们考虑怎么优化这个东西。
大概就是把边看成点,然后对于原来的一个点连的边按照权值排序,每条与和他(排序后)相邻的边连起来,边权就是增加的值(具体看代码吧),然后就是最短路了。
- 代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=4e5+10;
typedef long long ll;
typedef pair<long long,int> pli;
ll INF=1000000000000000000;
int n,m;
int S,T;
struct graph2{
int hed[M+10],nxt[M*4],to[M*4];ll val[M*4],cnt;
inline void adde(int u,int v,ll w){
cnt++;to[cnt]=v,nxt[cnt]=hed[u],val[cnt]=w;hed[u]=cnt;
}
priority_queue<pli,vector<pli>,greater<pli> >Q;
bool vis[M];ll dis[M];
inline void dij(int s){
for(int i=1;i<=T+1;i++)dis[i]=INF;
dis[s]=0;
Q.push(pli(dis[s],s));
while(!Q.empty()){
int u=Q.top().second;Q.pop();
if(vis[u])continue;
vis[u]=true;
for(int i=hed[u];i;i=nxt[i]){
int v=to[i];
if(dis[v]>dis[u]+val[i])Q.push(pli(dis[v]=dis[u]+val[i],v));
}
}
printf("%lld\n",dis[T]);
}
}G2;
bool cmp(const int,const int);
struct graph{
int hed[N],cnt,nxt[M],to[M];ll val[M];
inline void adde(int u,int v,ll w){
cnt++;to[cnt]=v,val[cnt]=w,nxt[cnt]=hed[u];hed[u]=cnt;
}
int E[N],tp;
inline void build(){
for(int x=1;x<=n;x++){
tp=0;
for(int i=hed[x];i;i=nxt[i]){
E[++tp]=i;
}
sort(E+1,E+tp+1,cmp);
for(int j=1;j<=tp;j++){
if(x==1)G2.adde(S,E[j],val[E[j]]);
if(to[E[j]]==n)G2.adde(E[j],T,val[E[j]]);
if(j!=1)G2.adde(E[j],E[j-1],0);
if(j!=tp)G2.adde(E[j],E[j+1],val[E[j+1]]-val[E[j]]);
G2.adde(E[j]^1,E[j],val[E[j]]);
}
}
}
}G;
bool cmp(const int a,const int b){return G.val[a]<G.val[b];}
int main()
{
G.cnt=1;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;ll w;scanf("%d%d%lld",&u,&v,&w);
G.adde(u,v,w);G.adde(v,u,w);
}
S=G.cnt+1,T=G.cnt+2;
G.build();
G2.dij(S);
}