首页 > 代码库 > 点分治基本膜版

点分治基本膜版

点分治基本的几个步骤吧

找根(保证平衡度最优)

从找到的根处理起,每次删去已有的根,分治其每一个子树

非暴力算法解决树形问题的有效方式

 


 

 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<vector> 5 #include<queue> 6 using namespace std; 7  8 inline int read(){ 9     char ch;10     int re=0;11     bool flag=0;12     while((ch=getchar())!=-&&(ch<0||ch>9));13     ch==-?flag=1:re=ch-0;14     while((ch=getchar())>=0&&ch<=9)  re=re*10+ch-0;15     return flag?-re:re;16 }17 18 struct edge{19     int to,w;20     edge(int to=0,int w=0):21         to(to),w(w){}22 };23 24 const int maxn=10001,maxm=50001;25 int n;26 vector<edge> G[maxn];27 int son[maxn],F[maxn],sum;28 bool vis[maxn];29 int root;30 31 inline void add_edge(int from,int to,int w){32     G[from].push_back(edge(to,w));33     G[to].push_back(edge(from,w));34 }35 36 void init(){37     n=read();38     for(int i=0;i<n-1;i++){39         int from=read(),to=read(),w=read();40         add_edge(from,to,w);41     }42 }43 44 void getroot(int x,int fa){45     son[x]=1;46     F[x]=0;47     int dd=G[x].size();48     for(int i=0;i<dd;i++){49         edge &e=G[x][i];50         if(e.to!=fa&&!vis[e.to]){51             getroot(e.to,x);52             son[x]+=son[e.to];53             F[x]=max(F[x],son[e.to]);54         }55     }56     F[x]=max(F[x],sum-son[x]);57     if(F[x]<F[root])  root=x;58 }59 60 void solve(int x){61     vis[x]=1;62     int dd=G[x].size();63     for(int i=0;i<dd;i++){64         edge &e=G[x][i];65         if(!vis[e.to]){66             root=0;67             sum=e.to;68             getroot(x,0);69             solve(e.to);70         }71     }72 }73 74 int main(){75     //freopen("temp.in","r",stdin);76     init();77     sum=F[root=0]=n;78     memset(vis,0,sizeof vis);79     getroot(1,0);80     printf("%d\n",root);81     memset(vis,0,sizeof vis);82     solve(root);83     return 0;84 }

 


理想永远都年轻  你让我倔强地反抗着命运

点分治基本膜版