codefor 14D:树的直径

题意:求树上两条不相交路径的最大乘积

 

题目要求两条路径不相交,而给的又是一棵生成树,所以断开任意一条边,都能把原图分成两个部分

所以我们枚举断开的边,在每一部分分别求树的直径,维护最大的乘积就是结果

#include"cstdio"
#include"queue"
#include"cmath"
#include"stack"
#include"iostream"
#include"algorithm"
#include"cstring"
#include"queue"
#include"map"
#include"set"
#include"vector"
#define ll long long
#define mems(a,b) memset(a,b,sizeof(a))
#define ls pos<<1
#define rs pos<<1|1

using namespace std;
const int MAXN = 205;
const int MAXE = 1005;
const int INF = 0x3f3f3f3f;

struct node{
    int e,next;
    node(){}
    node(int a,int b):e(a),next(b){};
}edge[MAXE];

int tot,first[MAXN],vis[MAXN];
int ans1,ans2,dep,pos;

int mat[MAXN][MAXN];

void init(){
    tot=0;
    mems(first,-1);
    mems(vis,0);
    mems(mat,0);
}

void addedge(int u,int v){
    edge[tot]=node(v,first[u]);
    first[u]=tot++;
    edge[tot]=node(u,first[v]);
    first[v]=tot++;
}

void dfs(int now,int cut,int depth){
    vis[now]=1;
    if(depth>=dep){
        dep=depth;
        pos=now;
    }
    for(int i=first[now];i!=-1;i=edge[i].next){
        int v=edge[i].e;
        if(vis[v]||v==cut) continue;
        dfs(v,cut,depth+1);
    }
}

int main(){
    int n;
    while(~scanf("%d",&n)){
        init();
        for(int i=1;i<n;i++){
            int u,v;scanf("%d%d",&u,&v);
            addedge(u,v);
            mat[u][v]=mat[v][u]=1;

        }
        int ans=0;
        for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++){
            if(!mat[i][j]) continue;
            dep=-1;
            mems(vis,0);
            dfs(i,j,0);
            dep=-1;
            mems(vis,0);
            dfs(pos,j,0);
            int t=dep;
            dep=-1;
            mems(vis,0);
            dfs(j,i,0);
            dep=-1;
            mems(vis,0);
            dfs(pos,i,0);
            ans=max(ans,t*dep);
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

 

posted @ 2016-01-19 20:56  Septher  阅读(154)  评论(0编辑  收藏  举报