今日では、イベントのすべてのNOIシリーズは、人工的なスタックが遠く、遠く離れた私たちを残している、時間のフルスタックをオープンしました。
だから、このブログでは、私が一緒にプレイしてもらうことです。
まず、C ++のgoto言葉遣いことは明らかである必要があります。
loop:;
…
goto loop;
後藤を実行している場合は、タグが後藤の前または後であってもよいし、対応するタグにジャンプします。
しかし、あなたはコンパイルエラーを発見したしようとしてみてください、
その理由は、操作がループとgoto文の間に新しい変数を(再帰も新しい変数を追加)を添加していないということです、あなたは二回あなたのコードはint kを想像することはできません。
最後に、我々はどのように、たとえば、それを変更するには?
ツリーをトラバース:
void dg(int x) {
siz[x] = 1;
for(int i = fi[x]; i; i = nt[i]) {
int y = to[i];
if(y == fa[x]) continue;
fa[y] = x;
dg(y);
siz[x] += siz[to[i]];
}
}
1.は、再帰的に使用されているすべての変数で最初に定義されています。
void dg(int x) {
int i, y;
siz[x] = 1;
for(i = fi[x]; i; i = nt[i]) {
y = to[i];
if(y == fa[x]) continue;
fa[y] = x;
dg(y);
siz[x] += siz[to[i]];
}
}
2.パラメータのDGを含むこれらの変数は、タイプを開くために、配列に保存する新しい名前は、現在のプログラムがどこから始めるべきであることを示しています。
int z0, ty[N], zx[N], zi[N], zy[N];
ループしながら、再帰的な手順を達成するために3。
すべてのwhileループは、変数のロードを開始し、その後、後藤に始まりました。
ダウンこの点で使用されるすべての変数は、現在位置はよく覚えて各再帰する前に、次の層の良いスタートが、先頭に戻ってジャンプし、フラグ再帰を設定した後、その後、スキップします。
int z0, ty[N], zx[N], zi[N], zy[N];
void dg(int x) {
ty[++ z0] = 0, zx[z0] = x;
while(z0) {
loop0 :;
int x = zx[z0], i = zi[z0], y = zy[z0];
if(ty[z0] == 1) goto loop1;
siz[x] = 1;
for(i = fi[x]; i; i = nt[i]) {
y = to[i];
if(y == fa[x]) continue;
fa[y] = x;
zx[z0] = x, zi[z0] = i, zy[z0] = y, ty[z0] = 1;
ty[++ z0] = 0, zx[z0] = y;
goto loop0;
//dg(y);
loop1 :;
siz[x] += siz[to[i]];
}
z0 --;
}
}
このような変更の利点は、変化の特に多数ではなく、簡単なエラー訂正、簡単な手動スタック文言として使用されていません。