SGU 4444 Travel(最短路+bfs)

来源:互联网 发布:qq超市数据清零 编辑:程序博客网 时间:2024/05/16 04:44


题意:给定一个完全图,其中有两种边,长度为a(不超过5e5)或长度为b(剩下的),求有1~n的最短路径(数据范围1e5)。

思路:这题的答案显然分为两种情况,第一种1到n的边长为b,这时我们要求长为a的这些边从1到n的最短路,因为边长都相同,一次bfs即可。

第二种情况是1到n的边长为a,此时我们要求长为b的这些边从1到n的最短路,因为边数太多,直接bfs肯定t,

考虑用一个set维护当前剩余的未到达点,每次将set中的长为a的边到达的点删去,然后bfs即可,这样做保证了每个点只被访问一次,时间复杂度为O(n*logn)。

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define LL long long#define pii pair<int, int>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 100100;const int INF = 0x3f3f3f3f;int n, m, a, b;int dist[MAXN];bool vis[MAXN];struct Edge {    int to,next;} edge[MAXN*10];int head[MAXN], tot;void init() {    tot = 0;    memset(head,-1,sizeof(head));}void addedge(int u, int v) {    edge[tot].to = v;    edge[tot].next = head[u];    head[u] = tot++;}LL bfs1() {queue<int> q;memset(vis, 0, sizeof(vis));q.push(1);vis[1] = 1;while(!q.empty() && !vis[n]) {int t = q.front(); q.pop();for(int i = head[t]; i != -1; i = edge[i].next) {int u = edge[i].to;if(vis[u]) continue;dist[u] = dist[t] + 1;vis[u] = 1;q.push(u);}}if(!vis[n]) return INF;else return (LL)dist[n]*a;}LL bfs2() {set<int> last;for(int i = 2; i <= n; i++) last.insert(i);queue<int> q;memset(vis, 0, sizeof(vis));q.push(1);vis[1] = 1;while(!q.empty() && !vis[n]) {int t = q.front(); q.pop();set<int> tmp;for(int i = head[t]; i != -1; i = edge[i].next) {int u = edge[i].to;if(vis[u]) continue;last.erase(u);tmp.insert(u);}for(set<int>::iterator it = last.begin(); it != last.end(); it++) {int u = *it;dist[u] = dist[t] + 1;vis[u] = 1;q.push(u);}last = tmp;}if(!vis[n]) return INF;else return (LL)dist[n]*b;}int main() {    //freopen("input.txt", "r", stdin);while(scanf("%d%d%d%d", &n, &m, &a, &b) == 4) {init();bool tag = 0;for(int i = 1, u, v; i <= m; i++) {scanf("%d%d", &u, &v);addedge(u, v);addedge(v, u);if(u==1&&v==n || u==n&&v==1) tag = 1;}LL ans;if(tag) ans = min((LL)a, bfs2());else ans = min((LL)b, bfs1());cout << ans << endl;}    return 0;}


0 0