Travel
The country frog lives in has n
towns which are conveniently numbered by 1,2,…,n
.
Among n(n−1)2
pairs of towns, m of them are connected by bidirectional highway, which needs a minutes to travel. The other pairs are connected by railway, which needs b
minutes to travel.
Find the minimum time to travel from town 1
to town n
.
Input
The input consists of multiple tests. For each test:
The first line contains 4
integers n,m,a,b (2≤n≤105,0≤m≤5⋅105,1≤a,b≤109). Each of the following m lines contains 2 integers ui,vi, which denotes cities ui and vi are connected by highway. (1≤ui,vi≤n,ui≠vi
).
Output
For each test, write 1
integer which denotes the minimum time.
Sample Input
3 2 1 3
1 2
2 3
3 2 2 3
1 2
2 3
Sample Output
2 3
分两种情况:
1. 1到 n 铁路可以直连 跑一次最短路取 Min(b,dist[n])
2. 1 到n 高速公路连通 那么我们BFS跑最短路 ,每次构一次新图,每个点入队一次.因为是完全图所以每次可以入队的点都非常多.所以可以暴力.
#include <iostream> #include <cstdio> #include <string.h> #include <queue> #include <algorithm> #include <math.h> using namespace std; typedef long long LL; const LL INF = 1e16; const LL N = 100005; struct Edge{ LL v,next; LL w; }edge[10*N]; LL head[N]; LL tot,n,m,a,b; bool vis[N]; LL low[N]; LL MIN ; void addEdge(LL u,LL v,LL w,LL &k){ edge[k].v = v,edge[k].w = w,edge[k].next = head[u],head[u]=k++; } struct Node{ int u; int step; }; void init(){ memset(head,-1,sizeof(head)); tot = 0; } void spfa(LL pos){ for(LL i=1;i<=n;i++){ low[i] = INF; vis[i] = false; } low[pos] = 0; queue<LL>q; while(!q.empty()) q.pop(); q.push(pos); while(!q.empty()){ LL u = q.front(); q.pop(); vis[u] = false; for(LL k=head[u];k!=-1;k=edge[k].next){ LL w = edge[k].w,v = edge[k].v; if(low[v]>low[u]+w){ low[v] = low[u]+w; if(!vis[v]){ vis[v] = true; q.push(v); } } } } } bool vis1[N]; int bfs(int pos){ memset(vis,0,sizeof(vis)); queue<Node> q; Node node; vis[pos] = 1; node.u = pos; node.step = 0; q.push(node); while(!q.empty()){ memset(vis1,false,sizeof(vis1)); node = q.front(); int u = node.u; int step = node.step; /// if((step+1)*b>a) return -1; TLE q.pop(); vis1[u] = 1; for(int k=head[u];k!=-1;k=edge[k].next){ int v = edge[k].v; vis1[v] = true; } Node next; if(!vis1[n]) return step+1; for(int i=n;i>=1;i--){ if(!vis1[i]&&!vis[i]){ if((step+1)*b>a) return -1; next.u = i; next.step = step+1; q.push(next); vis[i] = true; } } } return -1; } int main(){ while(scanf("%lld%lld%lld%lld",&n,&m,&a,&b)!=EOF){ init(); bool flag = false; for(int i=0;i<m;i++){ LL u,v; scanf("%lld%lld",&u,&v); addEdge(u,v,a,tot); addEdge(v,u,a,tot); if(u==1&&v==n||u==n&&v==1) flag = 1; } LL ans = 0; if(!flag){ spfa(1); ans = min(low[n],b); }else{ int step = bfs(1); if(step==-1) ans = a; else ans = min(a,step*b); } printf("%lld ",ans); } }