noip模拟赛 radius
2024-09-12 03:26:28
分析:这道题实在是不好想,一个可以骗分的想法是假定要求的那个点在中心点上,可以骗得不少分.但是在边上的点要怎么确定呢?理论复杂度O(﹢无穷).答案一定是和端点有关的,涉及到最大值最小,考虑二分最大值,关键就是怎么check.如果有一条边x,还有一个点y,把y到x上的点的距离>mid的点给标记上,这样就会形成许多个区间,判断一下x是否被这些区间给完全覆盖住了,如果没有被完全覆盖住,证明这个最大值可以更小.思路非常奇妙,具体实现细节可以参看代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = , maxm = ; int n, m, a[maxn][maxn], head[maxn], to[maxm],ans,len,top,nextt[maxm],w[maxm], tot = ;
struct node
{
int x, y, z;
}e[]; struct node2
{
int first, second;
}e2[]; void add(int x, int y, int z)
{
w[tot] = z;
to[tot] = y;
nextt[tot] = head[x];
head[x] = tot++;
} void floyd()
{
for (int k = ; k <= n; k++)
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
if (a[i][j] > a[i][k] + a[k][j])
a[i][j] = a[i][k] + a[k][j];
} void add2(int x, int y)
{
e2[++top].first = x;
e2[top].second = y;
} bool cmp(node2 a, node2 b)
{
if (a.first == b.first)
return a.second < b.second;
return a.first < b.first;
} bool can()
{
int x = ;
sort(e2 + , e2 + + top,cmp);
for (int i = ; i <= top; i++)
{
if (x < e2[i].first)
return false;
if (x > e2[i].second)
continue;
x = e2[i].second + ;
}
if (x > len)
return true;
return false;
} bool check(int p)
{
bool flag = false;
for (int i = ; i <= m; i++)
{
top = ;
len = e[i].z;
for (int j = ; j <= n; j++)
{
int x = p - a[e[i].x][j];
int y = p - a[e[i].y][j];
if (x < && y < )
{
add2(, e[i].z);
break;
}
if (x >= e[i].z || y >= e[i].z)
continue;
if (x + y >= e[i].z)
continue;
add2(max(, x + ), min(e[i].z, e[i].z - y - ));
}
if (!can())
flag = ;
if (flag)
break;
}
if (flag)
return true;
return false;
} int main()
{
memset(a, / , sizeof(a));
scanf("%d%d", &n, &m);
for (int i = ; i <= m; i++)
{
int u, v, z;
scanf("%d%d%d", &u, &v, &z);
z *= ;
add(u, v, z);
add(v, u, z);
e[i].x = u;
e[i].y = v;
e[i].z = z;
a[u][v] = a[v][u] = min(a[u][v], z);
}
for (int i = ; i <= n; i++)
a[i][i] = ;
floyd();
int l = , r = ;
while (l <= r)
{
int mid = (l + r) >> ;
if (check(mid))
{
ans = mid;
r = mid - ;
}
else
l = mid + ;
}
double temp = ans / 2.0;
printf("%.2lf\n", temp);
return ;
}
最新文章
- Unity3d_学习笔记_入门
- asdsa
- Error writing file‘frm‘(Errcode: 28)
- ZOJ 3329-One Person Game(概率dp,迭代处理环)
- Google的Protocol Buffer格式分析
- Noip2009提高组总结
- sql server 2012 数据库还原方法
- OpenCV+MFC显示图像
- JQuery OOP 及 OOP思想的简易理解
- NMF和SVD在推荐系统中的应用(实战)
- hdu4893 Wow! Such Sequence!
- 『cURL』curl: (6) Could not resolve host无法解析主机地址
- R语言的精度和时间效率比较(简单版)
- SharePoint Framework解决方案管理参考(二)
- VBA 删除Excel中所有的图片
- WPF TextBox控件中文字实现垂直居中
- nodejs async waterfull 小白向
- JavaEE Web 开发 链接 mysql 出现 Class.not found的错误
- 微信小程序调用微信登陆获取openid及用户信息 java做为服务端
- 00004 - test命令详解