1. 程式人生 > >P2610 [ZJOI2012]旅遊 樹的直徑

P2610 [ZJOI2012]旅遊 樹的直徑

i++ class algo 輸入格式 輸入輸出格式 tdi 超級 template duke

這個題就是建圖不太好建,但是我們一想,三角形貌似只能兩兩挨著,最後會變成一個二叉樹,所以問題就變成求樹的直徑。建圖用pair套map超級簡單。

題幹:

到了難得的暑假,為了慶祝小白在數學考試中取得的優異成績,小藍決定帶小白出去旅遊~~

經過一番抉擇,兩人決定將T國作為他們的目的地。T國的國土可以用一個凸N邊形來表示,N個頂點表示N個入境/出境口。T國包含N-2個城市,每個城市都是頂點均為N邊形頂點的三角形(換而言之,[b]城市組成了關於T國的一個三角剖分[/b])。[b]兩人的旅遊路線可以看做是連接N個頂點中不相鄰兩點的線段[/b]。

為了能夠買到最好的紀念品,小白希望旅遊路線上經過的城市盡量多。作為小藍的好友,你能幫幫小藍嗎?
輸入輸出格式
輸入格式:

每個輸入文件中僅包含一個測試數據。

第一行包含兩個由空格隔開的正整數N,N的含義如題目所述。

接下來有N
-2行,每行包含三個整數 p,q,r,表示該城市三角形的三個頂點的編號(T國的N個頂點按順時間方向從1至n編號)。 輸出格式: 輸出文件共包含1行,表示最多經過的城市數目。([b]一個城市被當做經過當且僅當其與線路有至少兩個公共點[/b])

代碼:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<map>
#include
<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) {
char c; bool op = 0; while(c = getchar(), c < 0 || c > 9) if(c == -) op = 1; x = c - 0; while(c = getchar(), c >= 0 && c <= 9) x = x * 10 + c - 0; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar(-), x = -x; if(x >= 10) write(x / 10); putchar(0 + x % 10); } const int N = 2e5 + 5; struct node { int l,r,nxt; }a[N << 1]; int n; int lst[N],len = 0; void add(int x,int y) { // cout<<x<<" "<<y<<endl; a[++len].l = x; a[len].r = y; a[len].nxt = lst[x]; lst[x] = len; a[++len].l = y; a[len].r = x; a[len].nxt = lst[y]; lst[y] = len; } int dep[N]; map <pair<int,int>,int> ys; void dfs(int x,int fa) { dep[x] = dep[fa] + 1; for(int k = lst[x];k;k = a[k].nxt) { int y = a[k].r; if(y == fa) continue; dfs(y,x); } } int main() { read(n); duke(i,1,n - 2) { int p,q,r; read(p);read(q);read(r); if(q > p) swap(p,q); if(r > p) swap(p,r); if(r > q) swap(q,r); if(!ys[pair<int,int>(p,q)]) { ys[pair<int,int>(p,q)] = i; } else add(i,ys[pair<int,int>(p,q)]); if(!ys[pair<int,int>(p,r)]) { ys[pair<int,int>(p,r)] = i; } else add(i,ys[pair<int,int>(p,r)]); if(!ys[pair<int,int>(q,r)]) { ys[pair<int,int>(q,r)] = i; } else add(i,ys[pair<int,int>(q,r)]); } int root = 1; dfs(1,0); for(int i = 2;i <= n - 2;i++) { if(dep[i] > dep[root]) root = i; } // dep[root] = 0; dfs(root,0); int ans = 0; for(int i = 1;i <= n - 2;i++) { if(dep[i] > ans) ans = dep[i]; } printf("%d\n",ans); return 0; }

P2610 [ZJOI2012]旅遊 樹的直徑