http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=184147
Description
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 .
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 ).
For each test, write 1 integer which denotes the minimum time.
3 2 1 3
1 2
2 3
3 2 2 3
1 2
2 3
2
3
/** SCU - 4444 别样最短路径-大数据完全图 题目大意:给定一个完全图,其中有两种边,长度为a(不超过5e5)或长度为b(剩下的),求有1~n的最短路径(数据范围1e5) 解题思路:如果1和n之间连边为a那么答案一定为a和一条最短的全由b组成的路径的较小者,如果1和n之间连边为b,那么答案一定 为b和一条最短的全由a组成的路径的较小者。对于第1种情况直接跑spfa就可以了,第二种情况由于边数较多,不能直接spfa 从1开始搜索与其相连的边权为b的边,用set维护一下,由于每个点只入队1次,复杂度还是允许的。这种处理方法还是第一 次做,感觉很巧妙 */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <set> #include <queue> using namespace std; typedef long long LL; const int INF=1e9+7; const int maxn=100100; int n,m,vis[maxn]; LL a,b,dis[maxn]; set<int>st,ts; set<int>::iterator it; int head[maxn],ip; void init() { memset(head,-1,sizeof(head)); ip=0; } struct note { int v,next; }edge[maxn*10]; void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++; } void spfa() { queue<int>q; for(int i=0;i<=n;i++)dis[i]=INF; memset(vis,0,sizeof(vis)); dis[1]=0; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dis[v]>dis[u]+1) { dis[v]=dis[u]+1; if(!vis[v]) { vis[v]=1; q.push(v); } } } } printf("%lld\n",min(dis[n]*a,b)); } void bfs() { dis[n]=INF; st.clear(),ts.clear(); for(int i=2;i<=n;i++)st.insert(i); queue<int>q; q.push(1); dis[1]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(st.count(v)==0)continue; st.erase(v),ts.insert(v); } for(it=st.begin();it!=st.end();it++) { q.push(*it); dis[*it]=dis[u]+1; } st.swap(ts); ts.clear(); } printf("%lld\n",min(dis[n]*b,a)); } int main() { while(~scanf("%d%d%lld%lld",&n,&m,&a,&b)) { init(); int flag=0; for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); if(u>v)swap(u,v); addedge(u,v); addedge(v,u); if(u==1&&v==n)flag=1; } if(flag)bfs(); else spfa(); } return 0; }