NOIP 2007 Senior 4
来源:互联网 发布:淘宝客怎么设置 编辑:程序博客网 时间:2024/05/29 15:13
传送门(洛谷)
这道题,数据规模相当小,n三次方随便搞,所以我们就先考虑求直径。
我们直接 O(n^3) Floyd 好了,然后 O(n ^ 2) 枚举直径端点。
设直径端点为u,v。如果有 floyd[u][i] + floyd[i][v] = floyd[u][v]
,我们就知道了 i 在直径上了。
于是我们又 O(n^2) 枚举点对,若两个点都在直径上并且距离小于S,它可能就是一个核了。所以怎么求偏心距呢?
离“准核”最远的点一定是直径的端点,否则它就不是直径端点了(因为有更远的)。所以可以 O(1) 查询。枚举核的时间复杂度 O(n^2)。
但是这是可以 hack 的。如果核的端点为直径的端点,偏心距显然不是0。因此特判一下,若枚举的“准核”为直径,就再用一个 O(n^2) 的算法求 ecc。具体点,一个枚举直径外的点,一个枚举直径内的点。
算法时间复杂度为 O(n^3) | O(n^2)。最主要的一点就是发现离“准核”最远的点一定是直径的端点,否则只能用 O(n^4) 甚至更高时间复杂度的算法。
参考代码
#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <string>#include <stack>#include <queue>#include <deque>#include <map>#include <set>#include <bitset>typedef int INT;using std::cin;using std::cout;using std::endl;inline INT readIn(){ INT a = 0; bool minus = false; char ch = getchar(); while (!(ch == '-' || (ch >= '0' && ch <= '9'))) ch = getchar(); if (ch == '-') { minus = true; ch = getchar(); } while (ch >= '0' && ch <= '9') { a = a * 10 + (ch - '0'); ch = getchar(); } if (minus) a = -a; return a;}inline void printOut(INT x){ char buffer[15]; INT length = 0; bool minus = x < 0; if (minus) x = -x; do { buffer[length++] = x % 10 + '0'; x /= 10; } while (x); if (minus) buffer[length++] = '-'; do { putchar(buffer[--length]); } while (length); putchar('\n');}const INT INF = (~(INT(1) << (sizeof(INT) * 8 - 1)));const INT maxn = 305;INT n, s;INT rect[maxn][maxn];void run(){ n = readIn(); s = readIn(); memset(rect, 0x3f, sizeof(rect)); for (int i = 1; i <= n; i++) rect[i][i] = 0; for (int i = 1; i < n; i++) { INT u = readIn(); INT v = readIn(); INT c = readIn(); rect[u][v] = rect[v][u] = c; } for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (i != j && j != k && k != i) rect[i][j] = std::min(rect[i][j], rect[i][k] + rect[k][j]); INT maxLen = 0; INT u, v; for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) { if (rect[i][j] > maxLen) { u = i; v = j; maxLen = rect[i][j]; } } INT ans = INF; for (int i = 1; i <= n; i++) if (rect[u][i] + rect[i][v] == maxLen) for (int j = i; j <= n; j++) if (rect[i][j] <= s && rect[u][j] + rect[j][v] == maxLen) { if (i != u || j != v) ans = std::min(ans, std::max(std::min(rect[u][i], rect[u][j]), std::min(rect[v][i], rect[v][j]))); else { INT ecc = 0; for (int a = 1; a <= n; a++) { INT temp = INF; if (rect[u][a] + rect[a][v] == maxLen) continue; for (int b = 1; b <= n; b++) if (rect[u][b] + rect[b][v] == maxLen) temp = std::min(temp, rect[a][b]); ecc = std::max(ecc, temp); } ans = std::min(ans, ecc); } } printOut(ans);}int main(){ run(); return 0;}
阅读全文
0 0
- NOIP 2007 Senior 4
- NOIP 2009 Senior 4
- NOIP 2011 Senior 4
- NOIP 2015 Senior 4
- NOIP 2013 Senior 4
- NOIP 2016 Senior 4
- NOIP 2008 Senior 4
- NOIP 2009 Senior 1
- NOIP 2009 Senior 3
- NOIP 2011 Senior 2
- NOIP 2011 Senior 3
- NOIP 2011 Senior 5
- NOIP 2011 Senior 6
- NOIP 2012 Senior 2
- NOIP 2012 Senior 5
- NOIP 2012 Senior 3
- NOIP 2015 Senior 2
- NOIP 2015 Senior 3
- 使用别名创建自己的命令之---alias
- MVP登陆模块
- ASP.NET MVC多语言处理中请求丢失或参数丢失
- 连续总结第二十二天
- xgboost在Windows下的安装
- NOIP 2007 Senior 4
- 学习笔记5
- ccpc2016杭州D题HDU5936
- 后缀数组2.0--Height数组(bzoj 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式)
- Storm概念、原理详解及其应用(二)Storm Cluster
- MVC三层模式解析
- Mac中jdk更新eclipse无法启动
- linux中yum命令的练习
- MVP的简单登录