您的位置:首页 > 其它

最小生成树 || ( 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:
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: