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; }