codeforce_exercise_r25

地铁修建(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的模板倒是练的比较熟悉了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值