Topic: Given a tree, it is required to divide the tree into pieces so that each block is between [b,3b]
"Hand in hand to teach you block tree series"
--finally figuring out how to do it.
--I got a code on the Internet, and it was a mistake.
--Fortunately, the idea is right.
The simple way to block is greedy and add to this method there is a serious efficiency problem can be Daisy card into O (n) block
So we can reserve a location for other blocks if the size of a piece is just >=b, divide this lump into pieces.
First select a point to start deep search maintain a stack each point exit recursion when the stack is merged from bottom to top
If a subtrees tree is deep and the number of elements in the stack is >=b, the current stack elements are merged into one block.
But the problem with this approach is that if a subtrees tree does not go deep into the B to search the next subtree, it may exceed B at some point within the next subtree.
This will cause the broken block to be disconnected.
So we maintain a stack every time we enter recursion, and for the current subtree the bottom of the stack is the bottom of the stack, and the elements below the bottom cannot be modified or stacked.
So that when a subtrees tree deep search because the subtree within the sub-block node does not exceed B, the number of previously searched not a block of nodes is not more than B, so each block not more than 2b
So why did the topic give 3b?
After the deep search, there may be some remaining nodes, the number of these nodes is not more than B, and must be connected with the last piece of the current
So we divide the remaining nodes into the last piece, which guarantees that the size of the last piece does not exceed 3b
A deep search can be solved.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1010using namespace Std;struct abcd{int to,next;} Table[m<<1];int head[m],tot;int n,b,cnt;int belong[m],root[m],stack[m],top;void Add (int x,int y) {Table[++tot]. To=y;table[tot].next=head[x];head[x]=tot;} void Dfs (int x,int from) {int i,bottom=top;for (i=head[x];i;i=table[i].next) if (table[i].to!=from) {DFS (table[i].to,x) ; if (top-bottom>=b) {root[++cnt]=x;while (Top!=bottom) belong[stack[top--]]=cnt;}} Stack[++top]=x;} int main () {int i,x,y;cin>>n>>b;for (i=1;i<n;i++) {scanf ("%d%d", &x,&y); ADD (x, y); ADD (y,x);} DFS (1,0), while (top) belong[stack[top--]]=cnt;cout<<cnt<<endl;for (i=1;i<=n;i++) printf ("%d%c", Belong[i],i==n? ' \ n ': '); for (i=1;i<=cnt;i++) printf ("%d%c", root[i],i==cnt? ') \ n ': '); return 0;}
Bzoj 1086 SCOI2005 Royal Federal Block tree