[USACO13OPEN]照片Photo

题目描述
Farmer John has decided to assemble a panoramic photo of a lineup of his N cows (1 <= N <= 200,000), which, as always, are conveniently numbered from 1…N. Accordingly, he snapped M (1 <= M <= 100,000) photos, each covering a contiguous range of cows: photo i contains cows a_i through b_i inclusive. The photos collectively may not necessarily cover every single cow.

After taking his photos, FJ notices a very interesting phenomenon: each photo he took contains exactly one cow with spots! FJ was aware that he had some number of spotted cows in his herd, but he had never actually counted them. Based on his photos, please determine the maximum possible number of spotted cows that could exist in his herd. Output -1 if there is no possible assignment of spots to cows consistent with FJ’s photographic results.

农夫约翰决定给站在一条线上的N(1 <= N <= 200,000)头奶牛制作一张全家福照片,N头奶牛编号1到N。

于是约翰拍摄了M(1 <= M <= 100,000)张照片,每张照片都覆盖了连续一段奶牛:第i张照片中包含了编号a_i 到 b_i的奶牛。但是这些照片不一定把每一只奶牛都拍了进去。

在拍完照片后,约翰发现了一个有趣的事情:每张照片中都有且仅有一只身上带有斑点的奶牛。约翰意识到他的牛群中有一些斑点奶牛,但他从来没有统计过它们的数量。 根据照片,请你帮约翰估算在他的牛群中最多可能有多少只斑点奶牛。如果无解,输出“-1”。

Input

输入格式

  • Line 1: Two integers N and M.

  • Lines 2…M+1: Line i+1 contains a_i and b_i.

输出格式

  • Line 1: The maximum possible number of spotted cows on FJ’s farm, or -1 if there is no possible solution.

输入输出样例
输入 #1复制
5 3
1 4
2 5
3 4
输出 #1复制
1
说明/提示
There are 5 cows and 3 photos. The first photo contains cows 1 through 4, etc.

From the last photo, we know that either cow 3 or cow 4 must be spotted. By choosing either of these, we satisfy the first two photos as well.


比较明显的差分约束。

但是呢,正解吧差分约束被卡了,我们怎么办呢?

这个时候就需要用到spfa的SLF优化,我们看当前的队首值与插入值比较,小于放到队首,否则放到队尾。

然后进队次数太大就返回-1(玄学)。

差分约束式子为:很简单,推一推就行。因为求最大值,所以跑最短路。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10;
int n,m,d[N];
int head[N],nex[N<<2],to[N<<2],w[N<<2],tot;
inline void add(int a,int b,int c){
	to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;
}
int spfa(){
	int vis[N]={0}; memset(d,0x3f,sizeof d); d[0]=0;
	deque<int> q;	q.push_back(0); vis[0]=1; int cnt=0;
	while(q.size()){
		int u=q.front();	q.pop_front();	vis[u]=0;
		for(int i=head[u];i;i=nex[i]){
			if(d[to[i]]>d[u]+w[i]){
				d[to[i]]=d[u]+w[i];
				if(!vis[to[i]]){
					if(++cnt>2e6)	return -1; vis[to[i]]=1;
					if(q.size()&&d[to[i]]>d[q.front()])	q.push_back(to[i]);
					else	q.push_front(to[i]);
				}
			}
		}
	}
	return d[n];
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)	add(i-1,i,1),add(i,i-1,0);
	for(int i=1,a,b;i<=m;i++)	
		scanf("%d %d",&a,&b),add(b,a-1,-1),add(a-1,b,1);
	cout<<spfa()<<endl;
	return 0;
}
全部评论

相关推荐

秋招进行到现在终于能写总结了。完全没想到战线会拉这么长,过程会如此狼狈,不过更应该怪自己太菜了。好在所有的运气都用在了最后,也是有个去处。背景:双2本硕科班,无竞赛,本科一段研究所实习,硕士一段大厂暑期实习但无转正。技术栈是C++&nbsp;&amp;&nbsp;Golang,实习是客户端音视频(而且是鸿蒙端开发),简历两个C++项目一个Golang项目。主要投递岗位:后端,cpp软开,游戏服务端,测开,以及一些不拘泥于Java的岗位。从8月起总共投递123家公司,笔试数不清了,约面大约30家。offer/oc/意向:友塔游戏(第一个offer,面试体验很好,就是给钱好少南瑞继保(计算机科班点击就送(限男生),不...
乡土丁真真:佬很厉害,羡慕~虽然我还没有到校招的时候,也想讲一下自己的看法:我觉得不是CPP的问题,佬的背书双2,技术栈加了GO,有两段实习。投了123,面了30.拿到11个offer。这个数据已经很耀眼了。这不也是CPP带来的吗?当然也不止是CPP。至少来说在这个方向努力过的也会有好的结果和选择。同等学历和项目选java就会有更好的吗?我个人持疑问态度。当然CPP在方向选择上确实让人头大,但是我觉得能上岸,至于最后做什么方向,在我看来并不重要。至于CPP特殊,有岗位方向的随机性,java不是不挑方向,只是没得选而已。也希望自己以后校招的时候能offer满满
点赞 评论 收藏
分享
10-13 17:47
门头沟学院 Java
wulala.god:图一那个善我面过,老板网上找的题库面的
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务