poj2376 Cleaning Shifts 贪心/最短路

哇这个题思路真的是妙(可能是因为自己太垃圾题见的太少)。题意差不多就是给你许多子区间,再给你一个大区间,问能覆盖整个大区间的最少小区间个数,如果不能覆盖,就输出-1。

这个题贪心意图挺明显的,但是代码还没实现(用嘴acksy233,给自己挖一个坑之后填上)。在同学和Hzwer大爷的提示下get到了个及其牛逼的做法。

思路就是先将大区间每个相邻点建一条权值为0的边(即代码line 40, 41),再读入每个数据,在小区间左端点(a)和小区间右端点(b)中建立一条权值为1的边。

然后借助Dijkstra来求出所建立图的最短路,最短路值dist[T]即为答案。

然后说下为什么Line44是addedge(a - 1, b, 1);。考虑一下输入是

2 4

1 2

3 4

的情况。按照题意来说,这个样例对应的输出应该是2。但是如果是addedge(a, b, 1);的话,2和3之间是不存在边的,也就不能正常的求得最短路了。


代码如下↓

#include <cstdio>
#include <queue>
#define inf 1000000000
#define P pair<int,int>
using namespace std;
struct node {
	int v, next, w;
}edge[1025100];
int dist[1025100], p[1025100], u, v, a, b, n, T, cnt;
priority_queue <P, vector<P>, greater<P> > q;
bool vis[1025100];
void addedge(int u, int v, int w) {
	edge[++cnt].v = v;
	edge[cnt].next = p[u];
	p[u] = cnt;
	edge[cnt].w = w;
}
void Dijkstra() {
	for (int i = 1; i <= T; i++)
		dist[i] = inf, vis[i] = false;
	dist[0] = 0;
	q.push(make_pair(0, 0));
	while (!q.empty()) {
		u = q.top().second;
		q.pop();
		if (vis[u])
			continue;
		vis[u] = true;
		for (int i = p[u]; i; i = edge[i].next) {
			v = edge[i].v;
			if (dist[v] > dist[u] + edge[i].w) {
				dist[v] = dist[u] + edge[i].w;
				q.push(make_pair(dist[v], v));
			}
		}
	}
}
int main() {
	scanf("%d%d", &n, &T); 
	for (int i = 1; i <= T; i++)
		addedge(i, i - 1, 0);
	for (int i = 1; i <= n; i++) {
		scanf("%d%d", &a, &b);
		addedge(a - 1, b, 1);
	}
	Dijkstra();
	if (dist[T] == inf)
		printf("-1\n");
	else
		printf("%d\n", dist[T]);
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值