cf14D Two Paths(树的直径)

题意:

N个点构成一棵树。树枝的长度都是1。

在当中找两条不相交【没有公共点】的路,使得二者长度之积最大。

(2 ≤ n ≤ 200)

思路:

一开始思路好麻烦,好麻烦,好麻烦,,,,,,,而且WA,,,,,

正解:

必定存在第三条路径连接两条最长路径。【因为是一棵树】。

去掉第三条路径上的某根树枝就可以将原树分成两个区域了,两条最长路径分别在一个区域里。

然后分别求两个区域的直径,相乘。

N不大,枚举。

代码:

int const N=210;

int n;
vector<int> G[N];
int g[N][N];
queue<int> Q;
int vis[N];

void Input(){
    cin>>n;

    mem(g,0);
    rep(i,1,n) G[i].clear();

    rep(i,1,n-1){
        int a,b;
        scanf("%d%d",&a,&b);
        G[a].push_back(b);
        G[b].push_back(a);
        g[a][b]=1;
        g[b][a]=1;
    }
}

int path(int x){ //从x出发,求直径
    mem(vis,-1);
    while(!Q.empty()) Q.pop();
    Q.push(x);
    vis[x]=0;
    while(!Q.empty()){
        int u=Q.front();    Q.pop();
        int L=G[u].size();
        rep(i,0,L-1){
            int v=G[u][i];
            if(g[u][v]==1 && vis[v]==-1){
                vis[v]=vis[u]+1;
                Q.push(v);
            }
        }
    }
    int ans=-1;
    int vv=-1;
    rep(i,1,n){
        if(vis[i]>ans){
            ans=vis[i];
            vv=i;
        }
    }
    while(!Q.empty()) Q.pop();
    mem(vis,-1);
    Q.push(vv);
    vis[vv]=0;
    while(!Q.empty()){
        int u=Q.front();    Q.pop();
        int L=G[u].size();
        rep(i,0,L-1){
            int v=G[u][i];
            if(g[u][v]==1 && vis[v]==-1){
                vis[v]=vis[u]+1;
                Q.push(v);
            }
        }
    }
    ans=-1;
    rep(i,1,n){
        if(vis[i]>ans){
            ans=vis[i];
        }
    }
    return ans;
}
void Solve(){
    int ans=0;
    rep(i,1,n-1){
        rep(j,i+1,n){
            if(g[i][j]==1){
                g[i][j]=g[j][i]=0;
                int x1=path(i);
                int x2=path(j);
                ans=max(ans,x1*x2);
                g[i][j]=g[j][i]=1;
            }
        }
    }
    printf("%d\n",ans);
}

int main(){

    Input();
    Solve();
    return 0;
}
时间: 2024-10-11 23:17:48

cf14D Two Paths(树的直径)的相关文章

Codeforces 14D Two Paths 树的直径

题目链接:点击打开链接 题意:给定一棵树 找2条点不重复的路径,使得两路径的长度乘积最大 思路: 1.为了保证点不重复,在图中删去一条边,枚举这条删边 2.这样得到了2个树,在各自的树中找最长链,即树的直径,然后相乘即可 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #includ

拓扑排序,树的直径模板(CF14D 枚举删边)

HDU4607 树的直径 #include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <vector> using namespace std; #define N 100005 #define INF 1<<30 int n,dis[N],E; bool vis[N]; vector<int>G[N]; //注意

树的直径| CF#615Div3 F. Three Paths on a Tree

F. Three Paths on a Tree 思路 两种方法: 1.两次bfs求树的直径,顺便求出一个直径端点到所有点的最短距离:再bfs一次,求另一个直径上的端点到其它所有点的最短距离:之后枚举第三个端点(不等于端点1和端点2),dis(a,b) + dis(b,c) + dis(a,c) 再除以 2 就是最终答案,因为每个路径走了两次所以除以2. 2.dfs求树的直径,记录直径上的所有点.从直径上的所有点去搜索它们到不在直径上的点的最远距离.最后直径+这个最远距离就是答案 代码1 bfs

[树的直径]F. Three Paths on a Tree

F. Three Paths on a Tree Description You are given an unweighted tree with nn vertices. Recall that a tree is a connected undirected graph without cycles. Your task is to choose three distinct vertices a,b,ca,b,c on this tree such that the number of

CodeForces 14D 树的直径 Two Paths

给出一棵树,找出两条不相交即没有公共点的路径,使得两个路径的长度的乘积最大. 思路:枚举树中的边,将该边去掉,分成两棵树,分别求出这两棵树的直径,乘起来维护一个最大值即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 200 + 10; 8 9

树的直径 Codeforces Beta Round #14 (Div. 2) D. Two Paths

tiyi:给你n个节点和n-1条边(无环),求在这个图中找到 两条路径,两路径不相交,求能找的两条路径的长度的乘积最大值: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack>

Codeforces1294F. Three Paths on a Tree(两次BFS求树的直径)

题意: 给一棵树,找到三个顶点,使三个顶点两两之间路径的并集最大 思路: 必定会有一组最优解,使得 a,b是树直径上的端点. 证明: 假设某个答案取连接点x.x最远的树到达的点是s,根据树的直径算法,s是树的某个直径a的端点.假设x的最远和第二远的点组成的链是b,b就会和a有一段公共部分.我们取a和b相交部分距离s最远的那个点y.那么取这个链上点y的答案一定比x更优 用两次BFS可以求出直径的两个端点,在这个过程中还能顺便求出一个端点到树上每一点的距离.之后再用一次BFS求得另一个端点到树上每一

Park Visit(树的直径)

传送门 Park Visit Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3721    Accepted Submission(s): 1667 Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! T

Gym - 100676H Capital City(边强连通分量 + 树的直径)

H. Capital City[ Color: Black ]Bahosain has become the president of Byteland, he is doing his best to make people's liveseasier. Now, he is working on improving road networks between the cities.If two cities are strongly connected, people can use BFS

树的直径求法与性质(附例题)

树的直径指树上距离最远的两点间的距离,它在树上问题上有许多应用,往往通过树的直径的性质可以将一个高时间复杂度的解法变为线性求解.对于树上两点间距离通常有三种定义,我们根据这三种情况分别讨论一下它的性质 树的直径的求法: 树的直径有两种求法,时间复杂度都是O(n) ①贪心求法: 贪心求直径的方法是任意找一个点为根,dfs整棵树找到距离他最远的点xx,再以这个点x为根求出距离它最远的点y,(x,y)即为直径 ②DP求法: DP求直径的方法是对于每个点记录这个点子树中的最长链及与最长链处于不同子树中的