求助
  • 板块CF704E Iron Man
  • 楼主_sys
  • 当前回复0
  • 已保存回复0
  • 发布时间2020/10/16 08:13
  • 上次更新2023/11/5 10:40:48
查看原帖
求助
49093
_sys楼主2020/10/16 08:13

WA29,答案比标准答案大了,但是我感觉我在所有地方都是在放宽精度,并且经过测试似乎不是 cross() 函数的问题而是作为答案的一对线段似乎就没有进 cross() 函数

#include <bits/stdc++.h>
using namespace std;
 
const int Maxn = 100005;
int n, m, cnt, dfn_cnt, fa[Maxn], dep[Maxn], head[Maxn], siz[Maxn], son[Maxn], top[Maxn], dfn[Maxn];
vector <pair <int, int> > tmp_Ve1, tmp_Ve2;
double T, mini, ans = 1e18;
struct line
{
	int l, r;
	double c, t;
	bool End(double Time = T)
	{
		return Time > t + (r - l) / c;
	}
};
vector <line> V, Ve[Maxn];
bool cmp1(line x, line y)
{
	return x.t < y.t;
}
struct cmp2
{
	bool operator () (const int x, const int y) const
	{
		return V[x].t + (V[x].r - V[x].l) / V[x].c > V[y].t + (V[y].r - V[y].l) / V[y].c;
	}
};
priority_queue <int, vector <int>, cmp2> Pr;
struct edg
{
	int nxt, to, w;
} edge[2 * Maxn];
void add(int x, int y)
{
	edge[++cnt] = (edg){head[x], y};
	head[x] = cnt;
}
void dfs1(int u, int f)
{
	fa[u] = f;
	dep[u] = dep[f] + 1;
	siz[u] = 1;
	for (int i = head[u]; i; i = edge[i].nxt)
	{
		int to = edge[i].to;
		if (to != f)
		{
			dfs1(to, u);
			siz[u] += siz[to];
			if (siz[to] > siz[son[u]]) son[u] = to;
		}
	}
}
void dfs2(int u, int tp)
{
	dfn[u] = ++dfn_cnt;
	top[u] = tp;
	if (son[u]) dfs2(son[u], tp);
	for (int i = head[u]; i; i = edge[i].nxt)
	{
		int to = edge[i].to;
		if (to != fa[u] && to != son[u]) dfs2(to, to);
	}
}
int lca(int x, int y)
{
	while (true)
	{
		if (top[x] == top[y]) return dep[x] < dep[y] ? x : y;
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		x = fa[top[x]];
	}
}
void spilt(double t, double c, int u, int v)
{
	tmp_Ve1.clear(), tmp_Ve2.clear();
	int l = lca(u, v);
	bool flag = false;
	while (u != l)
	{
		if (top[u] == top[l])
		{
			tmp_Ve1.push_back(make_pair(u, l));
			flag = true;
			break;
		}
		tmp_Ve1.push_back(make_pair(u, fa[top[u]]));
		u = fa[top[u]];
	}
	while (v != l)
	{
		if (top[v] == top[l])
		{
			tmp_Ve2.push_back(make_pair(l, v));
			flag = true;
			break;
		}
		tmp_Ve2.push_back(make_pair(fa[top[v]], v));
		v = fa[top[v]];
	}
	if (!flag) tmp_Ve1.push_back(make_pair(l, l));
	for (vector <pair <int, int> > :: iterator it = tmp_Ve1.begin(); it != tmp_Ve1.end(); it++)
	{
		int tp = dep[top[it -> first]] > dep[top[it -> second]] ? top[it -> first] : top[it -> second];
		Ve[tp].push_back((line){dep[it -> first] - dep[tp] + 2, dep[it -> second] - dep[tp] + 2, -c, t});
		t += (dep[it -> second] - dep[it -> first]) / (double) -c;
	}
	for (vector <pair <int, int> > :: reverse_iterator it = tmp_Ve2.rbegin(); it != tmp_Ve2.rend(); it++)
	{
		int tp = dep[top[it -> first]] > dep[top[it -> second]] ? top[it -> first] : top[it -> second];
		Ve[tp].push_back((line){dep[it -> first] - dep[tp] + 2, dep[it -> second] - dep[tp] + 2, c, t});
		t += (dep[it -> second] - dep[it -> first]) / (double) c;
	}
}
struct cmp3
{
	bool operator () (const int x, const int y) const
	{
		if ((T - V[x].t) * V[x].c + V[x].l != (T - V[y].t) * V[y].c + V[y].l)
			return (T - V[x].t) * V[x].c + V[x].l < (T - V[y].t) * V[y].c + V[y].l;
		return x < y;
	}
};
set <int, cmp3> Se;
double cross(int x, int y)
{
	double k1 = V[x].c, k2 = V[y].c;
	double b1 = V[x].l - V[x].t * k1, b2 = V[y].l - V[y].t * k2, result;
	if (abs(k1 - k2) <= 1e-9)
	{
		if (abs(b1 - b2) >= 1e-6) return 1e18;
		result = max(V[x].t, V[y].t);
	}
	else
	{
		result = (b1 - b2) / (k2 - k1);
		if (result + 1e-9 < V[x].t || result + 1e-9 < V[y].t || V[x].End(result - 1e-9) || V[y].End(result - 1e-9)) return 1e18;
	}
	return result;
}
void work(void)
{
	Se.clear();
	while (!Pr.empty()) Pr.pop();
	mini = 1e18;
	sort(V.begin(), V.end(), cmp1);
	for (int i = 0; i < (int) V.size(); i++)
	{
		T = V[i].t;
		if (T >= mini) return ;
		while (!Pr.empty() && V[Pr.top()].End())
			Se.erase(Pr.top()), Pr.pop();
		set <int, cmp2> :: iterator it = Se.insert(i).first;
		if (it != Se.begin())
		{
			it--;
			mini = min(mini, cross(*it, i));
			it++;
		}
		it++;
		if (it != Se.end())
			mini = min(mini, cross(*it, i));
		Pr.push(i);
	}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		add(x, y), add(y, x);
	}
	dfs1(1, 0), dfs2(1, 1);
	for (int i = 1; i <= m; i++)
	{
		double t, c;
		int u, v;
		scanf("%lf%lf%d%d", &t, &c, &u, &v);
		spilt(t, c, u, v);
	}
	for (int i = 1; i <= n; i++)
		if (top[i] == i) V = Ve[i], work(), ans = min(ans, mini);
	printf(ans == 1e18 ? "-1" : "%.10lf", ans);
	return 0;
}
2020/10/16 08:13
加载中...