[ZJOI2012]旅游
看懂题意就好了。
就是相邻的城市连边,然后求图的直径。
/**
* Problem:Journey
* Author:Shun Yao
* Time:2013.6.3
* Result:Accepted
*/
#include <cstring>
#include <cstdio>
#include <algorithm>
const long Maxn = 200005;
long abs(long x) {
return x < 0 ? -x : x;
}
long max(long x, long y) {
return x > y ? x : y;
}
long min(long x, long y) {
return x < y ? x : y;
}
class line {
public:
long u, v, i;
line() {}
~line() {}
line(long U, long V, long I):u(min(U, V)), v(max(U, V)), i(I) {}
} l[Maxn << 1];
bool cmpl(line a, line b) {
return a.u != b.u ? a.u < b.u : a.v < b.v;
}
class gnode {
public:
long v;
gnode *next;
gnode() {}
~gnode() {}
gnode(long V, gnode *ne):v(V), next(ne) {}
} *g[Maxn];
void add(long x, long y) {
g[x] = new gnode(y, g[x]);
g[y] = new gnode(x, g[y]);
}
long n, tot;
long q[Maxn], *L, *R;
long f[Maxn], d[Maxn][2];
long ans;
int main() {
static long i, a, b, c;
static gnode *e;
freopen("journey.in", "r", stdin);
freopen("journey.out", "w", stdout);
scanf("%ld", &n);
tot = 0;
for (i = 1; i <= n - 2; ++i) {
scanf("%ld%ld%ld", &a, &b, &c);
if (abs(a % n - b % n) > 1 && abs(a - b) > 1)
l[++tot] = line(a, b, i);
if (abs(a % n - c % n) > 1 && abs(a - c) > 1)
l[++tot] = line(a, c, i);
if (abs(b % n - c % n) > 1 && abs(b - c) > 1)
l[++tot] = line(b, c, i);
}
std::sort(l + 1, l + tot + 1, cmpl);
for (i = 1; i <= tot; i += 2)
add(l[i].i, l[i + 1].i);
memset(f, 0, sizeof f);
R = (L = &(*q = 1)) + 1;
f[1] = -1;
while (L != R) {
for (e = g[*L]; e; e = e->next)
if (!f[e->v])
f[*(R++) = e->v] = *L;
++L;
}
ans = 0;
do {
--L;
d[*L][0] = 0;
d[*L][1] = 0;
for (e = g[*L]; e; e = e->next)
if (f[e->v] == *L) {
if (d[*L][0] < d[e->v][0] + 1) {
d[*L][1] = d[*L][0];
d[*L][0] = d[e->v][0] + 1;
} else if (d[*L][1] < d[e->v][0] + 1)
d[*L][1] = d[e->v][0] + 1;
}
ans = max(ans, d[*L][0] + d[*L][1] + 1);
} while (L != q);
printf("%ld", ans);
fclose(stdin);
fclose(stdout);
return 0;
}
作者:HSUPPR
出处:http://www.cnblogs.com/hsuppr/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号