【ゲーム】HDU-5963友達

タイトル

ジュンBは男の子と女の子のグループがゲームをプレイするのを見ています。具体的には、ゲームは次のようになります。nノードのツリーが指定されている場合、このツリーの各エッジのウェイトは0または1。ゲームの開始時に、ノードがルートとして決定されます。次に、女の子から始めて、両側が交代で操作します。あるパーティが操作するとき、彼らは最初にルートではないポイントを選択し、そのポイントからその親へのエッジの重みが1であることを満たしている必要があります。次に、このポイントからルートノードへの単純なパスを見つけ、パス上のすべてのエッジの重みを反転しますつまり、0は1になり、1は0になります。一方の側が動作できない(つまり、すべての側の重みが0である)場合、もう一方の側が勝ちます。両方が最適な戦略を採用している場合、女の子は勝ち、「女の子が勝ちます!」を出力します。それ以外の場合は、「男の子が勝ちます!」を出力します。ゲームをより面白くするために、各ラウンド間の境界力を変更する操作があり、ゲームの各ラウンドに指定されたルートノードも異なる場合があります。具体的には、次のように境界線の太さを変更してゲームをプレイするためのm個の操作があります。∙ "0 x"は、xがゲームを開始するルートノードとして使用されている場合、どちらが勝つか、現在のツリーに問い合わせることを意味します。∙「1 xyz」は、xとyの間のエッジの重みをzに変更することを意味します。もちろん、Jun Bはその方法を知っています。しかし、彼はあなたをテストしたいと考えています。 
 
 

入力

最大5セットのテストデータが含まれます。最初の行には、データグループの数を示す正の整数があります。次に、各データグループの最初の行に、2つのスペースで区切られた2つの正の整数nとmがあり、それぞれ点の数​​と演算の数を表します。n、m <40000であることを確認します。次のn-1行は、3つの整数x、y、zの各行がツリーのエッジを表します。1 <x <n、1 <y <n、0 <= z <= 1であることを確認します。次のm行、1行に1つの操作、意味は上記のとおりです。上記の2つの形式のみが表示されることが保証されています。操作0の場合は1 <= x <= n、操作1の場合は1 <= x <= n、1 <= y <= n、0 <= z <= 1を確認し、ツリーにエッジ接続xがあることを確認しますそして、y。 
 
 
 

出力

各データセットのクエリ操作ごとに、「Boys win!」または「Girls win!」の行が出力されます。

入力例

2
2 3
1 2 0
0 1
1 2 1 1
0 2
4 11
1 2 1
2 3 1
3 4 0
0 1
0 2
0 3
0 4
1 2 1 0
0 1
0 2
0 3
1 3 4 1
0 3
0 4

出力例

男の子が勝つ!
女の子が勝つ!
女の子が勝つ!
男の子が勝つ!
女の子が勝つ!
男の子が勝つ!
男の子が勝つ!
女の子が勝つ!
女の子が勝つ!
男の子が勝つ!
女の子が勝つ!

分析

この質問は主にいくつかの勝つべき州を検討することです。
最初のケースは比較的単純なケースで、ルートノードの下のエッジの1つだけのウェイトが1の場合、女の子が勝つ必要があります。ルートノードが1つのエッジのみを接続し、重みが1であるとします。その後、いくつかのエッジを接続します。女の子が初めてフリップしたので、最初の面は0であり、男の子はこの面を回せないため、女の子が勝ちます。少年が逆転できると、最初のエッジが再び1になり、少女が再び0になる可能性があるため、この場合、操作の奇数が0になる可能性があるため、少女が勝つ必要があります。

質問のサンプルに従ってルールを分析していますが、質問の例は比較的単純です。分析後、合計で偶数回の操作が実行された場合は少年が勝利し、そうでない場合は少女が勝利すると結論付けることができます。各ノードに接続されているエッジの重みを記録します。奇数の場合は女の子が勝ち、そうでない場合は男の子が勝ちます。(これは自分で小さな絵を描いて描いたものです。なぜこれがルールなのか、よくわかりません。)

コード

#include <cstring> 
#include <cstdio> 
#include <iostream> 
#include <algorithm> 
#include <map> 
#include <vector>
 using  namespace std;
const  int INF = 0x3f3f3f3f ;
const  int N = 1e6 + 10 ; 
ベクトル <pair < intint >> p [N];
int sum [N];
int main(){
     int t; cin >> t;
    while(t-- ){
         int n、m;
        memset(合計、0sizeof (合計)); 
        
        scanf(" %d%d "、&​​n、&m);
        forint i = 0 ; i <n; i ++ 
            p [i] .clear(); 
        forint i = 1 ; i <= n- 1 ; ++ i){
             int x、y、z; 
            scanf(" %d%d%d "、&​​x、&y、&z); 
            p [x] .push_back(pair < intint > (y、z));
            p [y] .push_back(pair < intint > (x、z)); 
            sum [x] + = z; 
            sum [y] + = z; 
        } 
        forint i = 1 ; i <= m; ++ i){
             int x、y、z、op; 
            scanf(" %d "、&op);
            if(op == 0 ){ 
                scanf(" %d "、&x);
                if(sum [x]%2 == 0)printf(" Boys win!\ n "); else 
                printf(" 女の子が勝つ!\ n " ); 
            } else { 
                scanf(" %d%d%d "、&​​x、&y、&z);
                forint j = 0 ; j <p [x] .size(); j ++ if(p [x] [j] .first == y){ 
                        sum [x] -= p [x] [j]。第二; 
                        sum [x] + = z; 
                        p [x] [j] .second = z; 
                    } 
                forint j = 0 ; j <p [y] .size(); j ++ if(p [y] [j] .first == x){ 
                        sum [y] -= p [y] [j]。第二; 
                        sum [y] + = z; 
                        p [y] [j] .second = z; 
                    } 
            } 
        } 
    } 
 
 
    0を返し ます
}

 

おすすめ

転載: www.cnblogs.com/Vocanda/p/12689899.html