• LG2610旅游(dfs)


    LG2610旅游

    解题思路

    我们考虑把这张图转换一下。

    我们旅行完了一个国家后,无论我们从哪个节点出发,我们应该可以停留在任意剩下两个节点上。我们可以选择其旁边两个国家旅行。由于不能走回头路,另外一边就无法访问了。这样我们把有公共边的两个国家连边,可以构建出一张图。

    我们来探究这张图有什么性质。

    \(n\) 边形剖分可以得到 \(n-2\) 个三角形,\(n-3\) 表对角线。一条对角线对应一条边,一个三角对应一个点,因此这是一颗树。更进一步的,我们发现每个点度最大为 \(3\),这是一颗二叉树。

    于是问题就转化为了求树的直径。两边 dfs 即可。

    代码

    //Don't act like a loser.
    //This code is written by huayucaiji
    //You can only use the code for studying or finding mistakes
    //Or,you'll be punished by Sakyamuni!!!
    #include<bits/stdc++.h>
    using namespace std;
    
    int read() {
    	char ch=getchar();
    	int f=1,x=0;
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') {
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return f*x;
    }
    char read_char() {
    	char ch=getchar();
    	while(!isalpha(ch)) {
    		ch=getchar();
    	}
    	return ch;
    }
    
    const int MAXN=2e5+10;
    
    int n,cnt,dis[MAXN];
    int h[MAXN];
    
    struct edge {
    	int v,nxt;
    }e[MAXN<<1];
    
    void addedge(int u,int v) {
    	e[++cnt].v=v;
    	e[cnt].nxt=h[u];
    	h[u]=cnt;
    }
    void insert(int u,int v) {
    	addedge(u,v);
    	addedge(v,u);
    }
    
    void dfs(int u,int fa) {
    	for(int i=h[u];i;i=e[i].nxt) {
    		int v=e[i].v;
    		if(v!=fa) {
    			dis[v]=dis[u]+1; 
    			dfs(v,u);
    		} 
    	}
    }
    
    map<int,int> mp;
    int node(int x,int y) {
    	return x*MAXN+y;
    }
    
    void deal(int i,int a,int b) {
    	if(mp[node(a,b)]) {
    		insert(i,mp[node(a,b)]);
    	}
    	else {
    		mp[node(a,b)]=mp[node(b,a)]=i;
    	}
    }
    
    int main() {
    	cin>>n;
    	for(int i=1;i<=n-2;i++) {
    		int a,b,c;
    		a=read();b=read();c=read();
    		deal(i,a,b);deal(i,b,c);deal(i,c,a);
    	}
    	
    	dfs(1,0);
    	int rt=0;
    	for(int i=1;i<=n-2;i++) {
    		if(dis[i]>dis[rt]) {
    			rt=i;
    		}
    	}
    	dis[rt]=1;
    	dfs(rt,0);
    	rt=0;
    	for(int i=1;i<=n-2;i++) {
    		rt=max(rt,dis[i]);
    	}
    	cout<<rt<<endl;
    	
    	return 0;
    }
    
    
    
  • 相关阅读:
    P1312 [NOIP2011 提高组] Mayan 游戏
    Codeforces Round 736
    CF487E Tourists
    荏苒
    数论
    [NOI2009] 二叉查找树 题解
    元素
    线性基
    杂录
    SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别
  • 原文地址:https://www.cnblogs.com/huayucaiji/p/LG2610.html
Copyright © 2020-2023  润新知