2020年冬休み[gmoj2412] [クロックツリー] [DFS +隣接リスト]

タイトルの説明

ファーマージョンの新しいブルペンのデザインは非常に奇妙です。1... N(2≤N≤2500)の番号が付けられたN個の部屋とN-1個の廊下で構成されています。各廊下は2つの部屋を接続するため、各部屋はいくつかの廊下に沿って他の部屋に到達できます。
ブルペンの各部屋には、標準的な整数1 ... 12が文字盤に印刷された丸い時計が装備されています。ただし、これらの時計には針が1つしかなく、常にダイヤル上の数字を直接指します(2つの数字の間を指すことはありません)。
Cow Bessieは、すべてが整数12を指すように、牛舎のすべてのクロックを同期させたいと考えています。しかし、彼女の心は少し単純で、牛舎を歩くと、部屋に入るたびに部屋の時計の針を1つ後ろに動かします。たとえば、元のクロックが5を指していた場合は6を指し、元のクロックが12を指していた場合は1を指します。ベッシーが同じ部屋に何度も入る場合、彼女は入るたびにこの部屋の時計を回します。
Bessieがブルペンを歩き回り、すべての時計を12に向けられるように、可能な出発室の数を要求します。ベッシーは出発室の時計を回さないが、彼女が再び入ったときはいつでもそれを回すことに注意してください。時計はそれ自体では移動せず、ベッシーが入ったときにのみ移動します。さらに、Bessieが廊下に入ると、廊下の反対側の端に到達する必要があります(元の部屋に途中まで戻ることはできません)。

入力

入力の最初の行にはNが含まれています。次の行には、1〜12の範囲のN個の整数が含まれており、各部屋の初期クロック設定を示しています。次のN-1行のそれぞれは、2つの整数aとbの廊下を表しています。どちらも1 ... Nの範囲にあり、廊下で接続されている2つの部屋の番号です。

アウトプット

出発室の数を出力すると、Bessieがすべての時計を12に向けることができます。

入力例

4
11 10 11 11
1 2
2 3
2 4

出力例

1

データ範囲の制限

テストポイント1〜7はN≤100を満たします。
テストポイント8〜15には、追加の制限はありません。

プロンプト

この例では、ベッシーはすべての部屋の時計を12に向けることができます(たとえば、部屋1、2、3、2に移動し、最後に4に移動する)。

分析

この問題では、1つの部屋iをルートとして一度に列挙し、それに接続されている部屋を更新できます。質問はそれが完了できるかどうかを確認することなので、貪欲にそれを見て、父と息子の間を毎回行き来したいと思うかもしれません。子供が12に変わるまで、このとき父と息子の違いに応じて、uが何であるかを知ることができます。次に、次の子に移動して、uの値を決定します。すべての子が修正されるまで、現時点ではuは特定の数に固定されています。前のレベルに戻り、父親はuを12に変更しました。
したがって、このラウンドでは、ルートを除いて、最終的に他のポイントはすべて12になります。ルートがちょうど12の場合、それは可能であることを意味します。ルートが12でない場合はどうなりますか?実際、ルートは、ルートの最後の子で停止し、戻らないため、1です。このとき、ルートと最後の子の間の時間が1になります。これら2つのケースを除いて、他には何もありません。
if(edge [i] .y == v)continue;
必ずこの文を追加してください
そうしないと、無限にループします:タイトルは、2つの部屋が双方向のエッジであることを規定しているため、どのポイントでも、息子はその父親でもあります。、しかし、私たちは1つのポイントだけが根付くべきだと規定しています!

コードオン

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,a[5000],tot,t[5000],h[5000],ans;
struct node
{
	int x,y,next;
}b[5000];
void add(int xx,int yy)//邻接表 
{
	tot++;
	b[tot].x=xx;
	b[tot].y=yy;
	b[tot].next=h[xx];
	h[xx]=tot;
}
void dfs(int u,int v)
{
	for(int i=h[u];i;i=b[i].next)
	{
		if(b[i].y==v) continue;
		dfs(b[i].y,u);
		t[u]=(t[u]-t[b[i].y]+12)%12;
	}
} 
int main()
{
    freopen("clocktree.in","r",stdin);
    freopen("clocktree.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    	cin>>a[i];
    	a[i]%=12;//如果是12的话变成0 
	}
	int x,y;
	for(int i=1;i<=n-1;i++)
	{
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)
	{
		memcpy(t,a,sizeof(t));//百度找的,把a的所有东西复制到t里面
		dfs(i,0);//枚举根 
		if(t[i]==0||t[i]==1) ans++;//走一圈之后根是0或1都可以,是0就停下,是1就踩上去 
	}
	cout<<ans; 
    fclose(stdin);
    fclose(stdout);
    return 0;
}

公開された110元の記事 ウォンの賞賛100 ビュー8000

おすすめ

転載: blog.csdn.net/dglyr/article/details/105678451