最小生成树 || ( BFS && 二分答案) —— 营救
2017-04-27 14:08
274 查看
洛谷 1369 营救
“咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门……
妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了t区,而自己在s区。
该市有m条大道连接n个区,一条大道将两个区相连接,每个大道有一个拥挤度。小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐。所以请你帮她规划一条从s至t的路线,使得经过道路的拥挤度最大值最小。
输入格式:
第一行四个数字n,m,s,t。
接下来m行,每行三个数字
4000
,分别表示两个区和拥挤度。
(有可能两个区之间有多条大道相连。)
输出格式:
输出题目要求的拥挤度。
输入样例#1:
3 3 1 3 1 2 22 3 1
1 3 3
输出样例#1:
数据范围
30% n<=10
60% n<=100
100% n<=10000,m<=2n,拥挤度<=10000
题目保证1<=s,t<=n且s<>t,保证可以从s区出发到t区。
样例解释:
小明的妈妈要从1号点去3号点,最优路线为1->2->3。
Code 1 最小生成树解法
Code 2 BFS + 二分答案
题目描述
“咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门……妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了t区,而自己在s区。
该市有m条大道连接n个区,一条大道将两个区相连接,每个大道有一个拥挤度。小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐。所以请你帮她规划一条从s至t的路线,使得经过道路的拥挤度最大值最小。
输入输出格式
输入格式:第一行四个数字n,m,s,t。
接下来m行,每行三个数字
4000
,分别表示两个区和拥挤度。
(有可能两个区之间有多条大道相连。)
输出格式:
输出题目要求的拥挤度。
输入输出样例
输入样例#1:3 3 1 3 1 2 22 3 1
1 3 3
输出样例#1:
2
说明
数据范围30% n<=10
60% n<=100
100% n<=10000,m<=2n,拥挤度<=10000
题目保证1<=s,t<=n且s<>t,保证可以从s区出发到t区。
样例解释:
小明的妈妈要从1号点去3号点,最优路线为1->2->3。
Code 1 最小生成树解法
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define epx 10 using namespace std; const int MAX_E = 20000 + epx; const int MAX_V = 10000 + epx; struct Edge { int fm,to,dist; } e[MAX_E]; int fa[MAX_V],n,m,s,t; bool cmp(Edge a,Edge b) { return a.dist < b.dist; } int getfa(int x) { if (fa[x] == x) return fa[x]; else return fa[x] = getfa(fa[x]); } int same(int x,int y) { return getfa(x) == getfa(y); } void merge(int x,int y) { int fax = getfa(x),fay = getfa(y); fa[fax] = fay; } int main() { cin >> n >> m >> s >> t; for (int i=1;i<=m;i++) { cin >> e[i].fm >> e[i].to >> e[i].dist; } sort(e+1,e+m+1,cmp); for (int i=1;i<=n;i++) { fa[i] = i; } int rst = n,ans = -1; for (int i=1;i<=m && rst > 1;i++) { int x = e[i].fm,y = e[i].to; if (same(x,y)) continue; else { merge(x,y); rst--; ans = max(e[i].dist,ans); if (getfa(s) == getfa(t)) break; // 精髓 - 只要源点和终点被连接了,就可以退出了 } } printf("%d",ans); }
Code 2 BFS + 二分答案
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> #define MAXN 10005 using namespace std; struct edge { int vertex,weight; edge(int vv,int ww) { vertex = vv; weight = ww; } }; vector<vector<edge> > edges(MAXN); int vis[MAXN]; int xian[MAXN * 2]; int n,m,start,t; bool bfs(int val) { memset(vis,0,sizeof(vis)); queue<int> q; q.push(start); vis[start] = true; while(!q.empty()) { if (vis[t] == true) return true; // 在 val 的限制下,可以到达终点 int temp = q.front(); q.pop(); for (int i=0;i<edges[temp].size();i++) { if (edges[temp][i].weight > val) continue; if (!vis[edges[temp][i].vertex]) { q.push(edges[temp][i].vertex); vis[edges[temp][i].vertex] = true; } } } if (vis[t] == false) return false; // 在 val 的限制下,无法到达终点 } int main() { cin >> n >> m >> start >> t; start--; t--; for (int i=0;i<m;i++) { int fm,to,w; scanf("%d%d%d",&fm,&to,&w); fm--;to--; edges[fm].push_back(edge(to,w)); edges[to].push_back(edge(fm,w)); xian[i] = w; } sort(xian,xian+m); int l = 0,r = m - 1; int ans = 0x3f3f3f3f; while(l <= r) { int mid = (l + r)/2; if (bfs(xian[mid])) { r = mid - 1; ans = xian[mid]; } else { l = mid + 1; } } cout << ans; return 0; }
相关文章推荐
- Luogu P1396 营救【最小生成树/二分答案/最短路】 By celur925
- CH Round #72树洞[二分答案 DFS&&BFS]
- <二分答案加验证||最小生成树>bzoj 1821 部落划分
- [最小极差生成树 LCT || 二分答案 CDQ分治 并查集] Ural 2055 Urban Geography
- 51nod 1640 天气晴朗的魔法 【二分枚举最大生成树】or【最小&&最大 生成树】
- BZOJ 2654 tree(二分答案+最小生成树)
- bzoj2654 Tree 二分答案+最小生成树
- 修公路 最小生成树 二分答案
- 洛谷Oj-P2330 [SCOI2005]繁忙的都市-最小生成树+二分答案
- BZOJ4242:水壶(BFS & 最小生成树)
- 51nod1640-最小生成树&二分|性质-天气晴朗的魔法
- bzoj2654 二分答案+最小生成树
- [SCU 4525] meixiuxiu学图论 (二分答案 | 最小生成树)
- POJ 3026 Borg Maze & UVA 10307 Killing Aliens in Borg Maze(BFS,最小生成树)
- 【算法复习】图的最小生成树(Prim&Kruskal)
- sgu529. It's Time to Repair the Roads 简化版动态最小生成树
- HDOJ 1162 Eddy's picture(最小生成树 - kruskal)
- POJ1258--贪心&最小生成树的prim算法
- 最小生成树(kruskal&prim)畅通工程
- 图的邻接矩阵表示形式,DFS和BFS,最小生成树Prim和Kruscal,单源最短路径Dijkstra算法