现在的位置: 首页 > 综合 > 正文

BZOJ 2657 ZJOI 2012 旅游(journey) 树的直径

2018年01月19日 ⁄ 综合 ⁄ 共 1350字 ⁄ 字号 评论关闭

题目大意:给出一个凸多边形的三角剖分图,每一个三角形代表一个城市,现在连接这个图中的两个点,问最多能够经过多少个城市。

思路:浙江都是一帮神么。。

这题给的条件简直是不知所云啊。。转化十分巧妙。因为每个凸n边形经过三角剖分之后会出现n - 2个三角形,任意一条边只会成为两个城市的公共边或者整个多边形的边。不难推出两个城市的公共边是n - 3条,也就是说把公共边看成是新图的边的话,就会新图就会构成一颗树。之后就是很水的树的直径了。。。

CODE:

#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 200010
using namespace std;
#define max(a,b) ((a) > (b) ? (a):(b))
#define min(a,b) ((a) < (b) ? (a):(b))
 
int points;
map<pair<int,int>,int> G;
 
int head[MAX],total;
int next[MAX << 1],aim[MAX << 1];
 
inline void Add(int x,int y)
{
    next[++total] = head[x];
    aim[total] = y;
    head[x] = total;
}
 
int f[MAX];
 
void BFS(int start)
{
    static bool v[MAX];
    memset(v,false,sizeof(v));
    memset(f,0x3f,sizeof(f));
    static queue<int> q;
    while(!q.empty())   q.pop();
    q.push(start);
    f[start] = 0;
    while(!q.empty()) {
        int x = q.front(); q.pop();
        v[x] = true;
        for(int i = head[x]; i; i = next[i]) {
            if(v[aim[i]])   continue;
            f[aim[i]] = f[x] + 1;
            q.push(aim[i]);
        }
    }
}
 
int main()
{
    cin >> points;
    for(int x,y,z,i = 1; i <= points - 2; ++i) {
        scanf("%d%d%d",&x,&y,&z);
        pair<int,int> e(min(x,y),max(x,y));
        if(G.find(e) == G.end())
            G[e] = i;
        else {
            Add(i,G[e]);
            Add(G[e],i);
        }
        e = make_pair(min(y,z),max(y,z));
        if(G.find(e) == G.end())
            G[e] = i;
        else {
            Add(i,G[e]);
            Add(G[e],i);
        }
        e = make_pair(min(x,z),max(x,z));
        if(G.find(e) == G.end())
            G[e] = i;
        else {
            Add(i,G[e]);
            Add(G[e],i);
        }
    }
    BFS(1);
    int p = 0;
    f[0] = 0;
    for(int i = 1; i <= points - 2; ++i)
        if(f[i] > f[p])
            p = i;
    BFS(p);
    cout << *max_element(f + 1,f + points - 1) + 1 << endl;
    return 0;
}

抱歉!评论已关闭.