CODEFORCES GYM 2018 USP-ICPC G.Traffic Management、I.I Will Go(Dfs序)

G. Traffic Management:

在这里插入图片描述在这里插入图片描述
  题意:给n辆车的速度和当前位置,前车撞上后车时速度会变得和后车一样,后车速度不变,问最后一次撞击发生的时间。
  思路:从后往前遍历每一辆车,记录下每一辆车之后的车中的最小速度和此车所在的位置,计算当前车撞上最小速度车的时间,取max即为答案。
  数据范围:1e5
  时间复杂度:O(n)
  反思:同样还是从后往前遍历的思想。在春季选拔赛ICPC南昌网络赛中都有类似思想的题目,但都没有AC。
AC代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5;
const int inf = 0x3f3f3f3f;

int n;

struct NODE{
	int s, v;
	friend bool operator < (NODE a, NODE b){
		return a.s < b.s;
	}
}node[maxn + 5];

struct PP{
	int t, min_v, minv_pos;
}p[maxn + 5];

int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d %d", &node[i].s, &node[i].v);
	}
	sort(node + 1, node + 1 + n);//可能不需要sort,但题意没有说明是否是按照位置输入,保险起见
	p[n].min_v = node[n].v;
	p[n].minv_pos = node[n].s;
	float ans = 0;
	for(int i = n - 1; i >= 1; i--){
		if(p[i + 1].min_v >= node[i].v){//如果当前车的速度比之后所有车的速度小或等于最小速度,则永远追不上后车,此时更新最小速度和最小速度位置
			p[i].min_v = node[i].v;
			p[i].minv_pos = node[i].s;
		}
		else {//大于最小速度车则可以追上,此时计算追上时间并取max得到答案
			float dis = p[i + 1].minv_pos - node[i].s;
			float les = node[i].v - p[i + 1].min_v;
			float pos = dis / les;
			ans = max(ans, pos);
			p[i].min_v = p[i + 1].min_v;
			p[i].minv_pos = p[i + 1].minv_pos;
		}
	}
	printf("%.6f\n", ans);
	return 0;
}

I. I Will Go(Dfs序)

在这里插入图片描述
在这里插入图片描述
  题意:给出n个人和q个询问,再给出n个人要舔的对象,对每个询问给出a,b,输出当a去竞赛的时候b去不去竞赛。
  思路:建图,并记录入度,建完图遍历每个人,如果入度为0,则进入dfs,记录dfs序。预处理结束之后对每个询问O(1)查询a,b的L[a],R[a], L[b], R[b],如果L[b] < L[a] && R[b] > R[a],则代表a去的话b一定去。
  涉及算法:DFS序。
  数据范围:2e5
  时间复杂度:nlogn + q
  AC代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 1e5;

int n, q;
vector <int> G[maxn + 5];
int l[maxn + 5], r[maxn + 5];
int ind[maxn + 5];
int num;

void dfs(int x){
	l[x] = ++num;
	int len = G[x].size();
	for(int i = 0; i <= len - 1; i++){
		dfs(G[x][i]);
	}
	r[x] = num;
	return;
}
int main(){
	scanf("%d %d", &n, &q);
	for(int i = 0; i <= n - 1; i++){
		int v;
		scanf("%d", &v);
		if(v != -1){
			G[v].push_back(i);
			ind[i]++;
			//printf("---%d %d\n", v, i);
		}
	}
	for(int i = 0; i <= n - 1; i++){
		if(ind[i] == 0){
			dfs(i);
		}
	}
	for(int i = 1; i <= q; i++){
		int a, b;
		scanf("%d %d", &a, &b);
		//printf("%d %d %d %d\n", l[a], r[a], l[b], r[b]);
		if(l[b] <= l[a] && r[b] >= r[a]) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Educational Codeforces Round 146 (Rated for Div. 2)比赛中,有关于一个节点数量为n的问题。根据引用的结论,无论节点数量是多少,都可以将其分成若干个大小为2或3的区间使其错排,从而减少花费。根据引用的推导,我们可以通过组合数和差量来表示剩余的花费。而引用进一步推广了这个结论,可以使得任意长度的一段错排花费代价为边权和的两倍,并且通过贪心算法使得更多的边不被使用。以此来解决与节点数量相关的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Educational Codeforces Round 146 (Rated for Div. 2)(B,E详解)](https://blog.csdn.net/TT6899911/article/details/130044099)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Educational Codeforces Round 83 (Rated for Div. 2) D](https://download.csdn.net/download/weixin_38562130/14878888)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值