基环树,草稿
(有向图)基DP:https://ac.nowcoder.com/acm/contest/140/B
(无向图):bzoj3242 ,最小化最远距离。
(无向图):bzoj1791,求基环树直径。
(无向图):bzoj1040,基环树最大独立基。
#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=200010; int Laxt[maxn],Next[maxn],To[maxn],Len[maxn],cnt=1; int r[maxn],vis[maxn],tot; ll L[maxn],sum[maxn],ans,dp[maxn],p[maxn]; void add(int u,int v,int w) { Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Len[cnt]=w; } bool dfs(int u,int f) { if(vis[u]==1) { vis[u]=2; r[++tot]=u;L[tot]=Len[f]; return true;} //开始出现环 vis[u]=1; for(int i=Laxt[u];i;i=Next[i]){ if(i==(f^1)) continue; if(dfs(To[i],i)) { if(vis[u]==2) return false; //环遍历完了 else {vis[u]=2; r[++tot]=u; L[tot]=Len[f]; return true;} } } return false; } void treedp(int u,int f) //得到外向树的直径 { for(int i=Laxt[u];i;i=Next[i]){ if(i==(f^1)||vis[To[i]]==2) continue; treedp(To[i],i); ans=max(ans,dp[u]+Len[i]+dp[To[i]]); dp[u]=max(dp[u],dp[u]+Len[i]); } } ll A[maxn],B[maxn],C[maxn],D[maxn]; void solve() { ll P=0; rep(i,1,tot) p[i]=dp[r[i]],sum[i+1]=L[i]; rep(i,1,tot) P+=sum[i],A[i]=max(A[i-1],P+p[i]); P=0; for(int i=tot;i>=1;i--){ P+=sum[] } ans=max(ans,res); } int main() { int N,u,v,w; scanf("%d",&N); rep(i,1,N) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } dfs(1,0); rep(i,1,tot) treedp(r[i],0); solve(); printf("%.2lf\n",1.0*ans/2); return 0; }
It is your time to fight!