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;
}