题解 P2610 【[ZJOI2012]旅游】
今天模拟赛考了这道题,那就来水一篇题解吧。。。(话说提高组模拟赛考什么省选题啊??)
这道题要我们求一条线段最多能经过的三角形数量。
回想小学学过的奥数,老师告诉过我们这样一件事:`点无大小 线无粗细`。
既然如此,为什么不能把这条线段看成一条巨大的把三角形看成点呢?
那么本题的思路就出来了:我们把三角形看成点,然后建立一颗二叉树,在树上跑两边BFS求直径就可以了。
可是为什么我们一定能建成二叉树呢?
其实很好证明。
三角形只有三条边,那么最多能有一个父亲和两个儿子,所以是二叉树。
当然,这个东西不是特别重要。
重点是,我们接下来怎么建图?
这里我是这样解决的:
先把每一条边都存进一个map里面,然后map手写结构体统计边出现的次数。
然后遍历一遍map,把所有出现不止一次的边两端的三角形连在一起。
这个办法唯一的问题是常数比较大,写的丑就容易TLE(然而机房的lemon竟然可以AC!)。
AC代码如下:
955ms 38272kb
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 namespace StandardIO{ 6 7 template<typename T>inline void read(T &x){ 8 x=0;T f=1;char c=getchar(); 9 for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; 10 for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0'; 11 x*=f; 12 } 13 14 template<typename T>inline void write(T x){ 15 if(x<0)putchar('-'),x*=-1; 16 if(x>=10)write(x/10); 17 putchar(x%10+'0'); 18 } 19 20 } 21 22 using namespace StandardIO; 23 24 namespace Solve{ 25 26 const int N=200001; 27 28 int n; 29 struct __normal_pair{ 30 int first,second; 31 inline bool operator < (const __normal_pair &x)const{ 32 if(first==x.first)return second<x.second; 33 return first<x.first; 34 } 35 }; 36 struct __store_pair{ 37 int first,second,size; 38 inline void push_back(int id){ 39 if(size++)second=id; 40 else first=id; 41 } 42 }; 43 map<__normal_pair,__store_pair>edge; 44 vector<int>graph[N]; 45 int dis[N],vis[N]; 46 47 inline __normal_pair make_pair(int f,int s){ 48 return (__normal_pair){f,s}; 49 } 50 inline void sor(int &a,int &b,int &c){ 51 if(a>b)swap(a,b); 52 if(a>c)swap(a,c); 53 if(b>c)swap(b,c); 54 } 55 inline int bfs(int s,int time){ 56 queue<int>q; 57 dis[s]=0,vis[s]=time; 58 q.push(s); 59 int final; 60 while(!q.empty()){ 61 final=q.front();q.pop(); 62 for(register vector<int>::iterator i=graph[final].begin();i!=graph[final].end();++i){ 63 if(vis[*i]==time)continue; 64 vis[*i]=time,dis[*i]=dis[final]+1; 65 q.push(*i); 66 } 67 } 68 return final; 69 } 70 71 inline void solve(){ 72 read(n); 73 for(register int i=1;i<=n-2;++i){ 74 int p,q,r; 75 read(p),read(q),read(r); 76 sor(p,q,r); 77 edge[make_pair(p,q)].push_back(i); 78 edge[make_pair(q,r)].push_back(i); 79 edge[make_pair(p,r)].push_back(i); 80 } 81 for(register map<__normal_pair,__store_pair>::iterator i=edge.begin();i!=edge.end();++i){ 82 if(i->second.size>1){ 83 graph[i->second.first].push_back(i->second.second); 84 graph[i->second.second].push_back(i->second.first); 85 } 86 } 87 write(dis[bfs(bfs(1,1),2)]+1); 88 } 89 90 } 91 92 using namespace Solve; 93 94 int main(){ 95 // freopen("triangulation9.in","r",stdin); 96 // freopen("triangulation.out","w",stdout); 97 solve(); 98 }