地铁修建(csp201703-4) :
问题描述
题目简述
A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁。
地铁由很多段隧道组成,每段隧道连接两个交通枢纽。经过勘探,有m段隧道作为候选,两个交通枢纽之间最多只有一条候选的隧道,没有隧道两端连接着同一个交通枢纽。
现在有n家隧道施工的公司,每段候选的隧道只能由一个公司施工,每家公司施工需要的天数一致。而每家公司最多只能修建一条候选隧道。所有公司同时开始施工。
作为项目负责人,你获得了候选隧道的信息,现在你可以按自己的想法选择一部分隧道进行施工,请问修建整条地铁最少需要多少天。
输入/输出格式
输入格式:
输入的第一行包含两个整数n, m,用一个空格分隔,分别表示交通枢纽的数量和候选隧道的数量。
第2行到第m+1行,每行包含三个整数a, b, c,表示枢纽a和枢纽b之间可以修建一条隧道,需要的时间为c天。
输出格式:
输出一个整数,修建整条地铁线路最少需要的天数。
样例
输入样例:
6 6
1 2 4
2 3 4
3 6 7
1 4 2
4 5 5
5 6 6
输出样例:
6
问题分析
解题思路
好巧不巧,这个题和我们这学期的算法考试最后一道题一摸一样。满满的熟悉感。不过抛开这一点,其实还是比较裸的dijkstra的题目了。但是这道题在最短路上做了一点文章:它不是求路程最短,而是求最长路最短。稍微有点绕,但是其实就是把原来dijkstra记录最短路的长度改成到该点的路径上的最长路的长度即可。总的来说还是比较简单的。
参考代码
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int inf=30000005;
class edge
{
public:
int from;
int to;
int weight;
edge(int u,int v,int w)
{
from=u;
to=v;
weight=w;
}
};
class heapnode
{
public:
int index;
int weight;
heapnode(int id,int w)
{
index=id;
weight=w;
}
bool operator <(const heapnode& hn) const
{
return weight>hn.weight;
}
};
priority_queue<heapnode> pq;
vector<edge> edges;
vector<int> points[100100];
int vis[100100];
int dis[100100];
int n,m;
void init()
{
for(int i=0;i<100100;i++)
{
points[i].clear();
dis[i]=inf;
}
edges.clear();
memset(vis,0,sizeof(vis));
}
void addedge(int a,int b,int c)
{
edge e1(a,b,c);
edges.push_back(e1);
points[a].push_back(edges.size()-1);
edge e2(b,a,c);
edges.push_back(e2);
points[b].push_back(edges.size()-1);
}
int dijkstra()
{
heapnode h(1,0);
pq.push(h);
dis[1]=0;
int count=0;
while(count<n)
{
heapnode tp=pq.top();
pq.pop();
if(vis[tp.index]==1) continue;
vis[tp.index]=1;
if(vis[n]==1) return dis[n];
count++;
int p_id=tp.index;
for(int i=0;i<points[p_id].size();i++)
{
edge te=edges[points[p_id][i]];
int tag_dis=max(dis[p_id],te.weight);
if(tag_dis<dis[te.to])
{
dis[te.to]=tag_dis;
heapnode nh(te.to,dis[te.to]);
pq.push(nh);
}
}
}
}
int main()
{
init();
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
addedge(a,b,c);
}
printf("%d",dijkstra());
return 0;
}
心得体会
这个题和16年9月的第四题其实挺像的,都是关于dijkstra问题的变形。总之dij的模板倒是练的比较熟悉了。