题意:
给
n
个点,
分析:
拆点最短路,由于到达每个点的状态不光与点
u
有关,也和到达
吐槽:
拆点建边的时候蠢了,然后 pair<int,int> 这种东西居然 TLE !!!
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair <int,int> PII;
typedef vector <int> VI;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int maxn = 100010;
const LL inf = 1LL<<60;
int tot,n,m,a[maxn],b[maxn],c[maxn],t[maxn];
VI g[maxn*20];
int head[maxn*20],edge_cnt;
map <PII,int> hs;
struct Edge{
int nt,to;
int val;
}edge[maxn*20];
void addedge(int u,int v,int val){
edge[edge_cnt].to = v;
edge[edge_cnt].val = val;
edge[edge_cnt].nt = head[u];
head[u] = edge_cnt++;
}
long long dp[maxn*20];
struct Node{
int fi,se;
Node(){}
Node(int a,int b) : fi(a),se(b){}
bool operator < (const Node &rhs) const{
return fi > rhs.fi;
}
};
void dijska(int st){
for(int i = 0;i < tot;++ i) dp[i] = inf;
dp[st] = 0;
priority_queue <Node> q;
q.push(Node(dp[st],st));
while(!q.empty()){
Node x = q.top(); q.pop();
int u = x.se;
if(x.fi != dp[u]) continue;
for(int i = head[u];i != -1;i = edge[i].nt){
int v = edge[i].to;
if(dp[v] > dp[u]+edge[i].val){
dp[v] = dp[u]+edge[i].val;
q.push(Node(dp[v],v));
}
}
}
}
int main(){
freopen("test.in","r",stdin);
while(~scanf("%d%d",&n,&m)){
//printf("%lld\n",inf);
edge_cnt = 0;
memset(head,-1,sizeof(head));
hs.clear();
for(int i = 1;i <= maxn*10;++ i) g[i].clear();
for(int i = 1;i <= m;++ i){
scanf("%d%d%d%d",a+i,b+i,c+i,t+i);
g[a[i]].pb(c[i]);
g[b[i]].pb(c[i]);
}
tot = 1;
for(int i = 1;i <= n;++ i){
sort(g[i].begin(),g[i].end());
g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
for(int j = 0;j < (int)g[i].size();++ j){
if(j){
addedge(tot,tot-1,g[i][j]-g[i][j-1]);
addedge(tot-1,tot,g[i][j]-g[i][j-1]);
}
hs[mp(i,g[i][j])] = tot++;
}
}
for(int i = 1;i <= m;++ i){
int u = hs[mp(a[i],c[i])],v = hs[mp(b[i],c[i])];
addedge(u,v,t[i]);
addedge(v,u,t[i]);
}
for(int i = 0;i < (int)g[1].size();++ i){
int v = hs[mp(1,g[1][i])];
addedge(0,v,0);
addedge(v,0,0);
}
dijska(0);
LL ans = inf;
for(int i = 0;i <(int)g[n].size();++ i){
int v = hs[mp(n,g[n][i])];
ans = min(ans,dp[v]);
}
printf("%lld\n",ans);
}
return 0;
}