最小最大边-地铁修建
题目大意:
A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁。
地铁由很多段隧道组成,每段隧道连接两个交通枢纽。经过勘探,有m段隧道作为候选,两个交通枢纽之间最多只有一条候选的隧道,没有隧道两端连接着同一个交通枢纽。
现在有n家隧道施工的公司,每段候选的隧道只能由一个公司施工,每家公司施工需要的天数一致。而每家公司最多只能修建一条候选隧道。所有公司同时开始施工。
作为项目负责人,你获得了候选隧道的信息,现在你可以按自己的想法选择一部分隧道进行施工,请问修建整条地铁最少需要多少天。
思路:
题目第一眼看过去以为是最小生成树,其实应该是和A*类似,具体正确性,我也没有做具体的深入思考,大概应该是每次搜到一个点的时候它的mincost应该是前驱结点的mincost和当前的边权取一个较大的值,但是要保证这个最大值最小,所以第一次访问到该点的时候就肯定是最小最大边
代码:
#include <iostream> #include <algorithm> #include <queue> #include <map> #include <cstring> using namespace std; const int N = 1e5+10; const int M = 4e5+10; struct edg{ int a,b,c; edg(){} edg(int a,int b,int c){ this->a=a; this->b=b; this->c=c; } bool operator < (const edg& x)const{ return this->c>x.c; } }; vector<edg> edgs[N]; priority_queue<edg> q; int vi[N]; int minc[M]; int main(){ int n,m; cin>>n>>m; for(int i=0;i<m;i++){ int a,b,c; cin>>a>>b>>c; edgs[a].push_back(edg(a,b,c)); edgs[b].push_back(edg(b,a,c)); } memset(minc,0x3f,sizeof minc); minc[1]=0; vi[1]=1; for(int i=0;i<edgs[1].size();i++){ q.push(edgs[1][i]); } while(q.size()){ edg t=q.top(); q.pop(); int a=t.a; int b=t.b; vi[b]=1; int c=t.c; minc[b]=min(minc[b],max(minc[a],c)); if(b==n)break; for(int i=0;i<edgs[b].size();i++){ if(!vi[edgs[b][i].b]){ q.push(edgs[b][i]); } } } cout<<minc[n]<<endl; }

浙公网安备 33010602011771号