2015 四川省赛 I Travel(bfs)
2015-10-02 17:29
459 查看
题意:
给定N<=105的无向完全图,给出其中M<=5×105条边,边权为a,其余边权为b,求1−>n最短路
分析:
分类讨论即可:
a<b时如果1−>n在给出的图上那么答案显然是a,反之那么1−>n边在当前图的补图上,答案就是min(当前图的dis[n]∗a,b)
a>=b时如果1−>n在给出的图的补图上那么答案显然是b,反之那么1−>n边在当前图上,答案就是min(补图的dis[n]∗b,a)
关于补图bfs的时候由于图巨大,不能存储,我们可以con[v]=u判断当前点所连的边是不是在原图上,在就跳过这个边
同时为了保证复杂度我们用set来维护剩余没有得到最短路的顶点集合,这样就保证遍历的复杂度是O(max(n,m))了
问题得以解决
坑: set遍历的时候,有删除操作红黑树会调整,所以需要重新查找下一个值来继续遍历
代码:
给定N<=105的无向完全图,给出其中M<=5×105条边,边权为a,其余边权为b,求1−>n最短路
分析:
分类讨论即可:
a<b时如果1−>n在给出的图上那么答案显然是a,反之那么1−>n边在当前图的补图上,答案就是min(当前图的dis[n]∗a,b)
a>=b时如果1−>n在给出的图的补图上那么答案显然是b,反之那么1−>n边在当前图上,答案就是min(补图的dis[n]∗b,a)
关于补图bfs的时候由于图巨大,不能存储,我们可以con[v]=u判断当前点所连的边是不是在原图上,在就跳过这个边
同时为了保证复杂度我们用set来维护剩余没有得到最短路的顶点集合,这样就保证遍历的复杂度是O(max(n,m))了
问题得以解决
坑: set遍历的时候,有删除操作红黑树会调整,所以需要重新查找下一个值来继续遍历
代码:
// // Created by TaoSama on 2015-10-01 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; const int M = 1e6 + 10; int n, m, a, b, T; bool des ; int head , pnt[M], nxt[M], cnt; void add_edge(int u, int v) { pnt[cnt] = v; nxt[cnt] = head[u]; head[u] = cnt++; } int dp , con ; int bfs() { queue<int> q; memset(dp, 0x3f, sizeof dp); dp[1] = 0; q.push(1); while(q.size()) { int u = q.front(); q.pop(); for(int i = head[u]; ~i; i = nxt[i]) { int v = pnt[i]; if(dp[v] == INF) { dp[v] = dp[u] + 1; if(v == n) return dp[v]; q.push(v); } } } return dp ; } int cbfs() { queue<int> q; memset(dp, 0x3f, sizeof dp); memset(con, 0, sizeof con); set<int> s; for(int i = 2; i <= n; ++i) s.insert(i); dp[1] = 0; q.push(1); while(q.size()) { int u = q.front(); q.pop(); for(int i = head[u]; ~i; i = nxt[i]) con[pnt[i]] = u; int v = -1; while(true) { set<int>::iterator iter = s.upper_bound(v); if(iter == s.end()) break; v = *iter; if(con[v] != u) { s.erase(iter); dp[v] = dp[u] + 1; if(v == n) return dp[v]; q.push(v); } } } return dp ; } inline int read() { char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d%d%d", &n, &m, &a, &b) == 4) { bool ori = false; cnt = 0; memset(head, -1, sizeof head); memset(des, false, sizeof des); for(int i = 1; i <= m; ++i) { int u = read(), v = read(); if(u > v) swap(u, v); add_edge(u, v); add_edge(v, u); if(v == n) des[u] = true; if(u == 1 && v == n) ori = true; } long long ans; if(a < b) { if(ori) ans = a; else { ans = min(0LL + b, 1LL * a * bfs()); } } else { if(!ori) ans = b; else { ans = min(0LL + a, 1LL * b * cbfs()); } } printf("%lld\n", ans); } return 0; }
相关文章推荐
- Surrounded Regions
- Word Ladder, Gray Code
- UVA 11624
- HDU1495
- HDU2612 Find a way
- HDU1241 Oil Deposits
- Hdu2444二分图
- 最少步数BFS
- 转v_JULY_v的 BFS和DFS优先搜索算法
- 2015 寒假搜索专题 I - Meteor Shower(BFS)
- Same Tree
- E - Roads in the North
- DFS&BFS算法总结(1)
- Word Ladder I
- 图的BFS和DFS学习笔记
- [LeetCode] Binary Tree Level Order Traversal
- [LeetCode] Binary Tree Level Order Traversal II
- 关于BFS搜索的思想, 最简单的水题,不过深有体会啊。
- Word Ladder II
- Surrounded Regions