HDU-5963 Friends thinking

Title link http://acm.hdu.edu.cn/showproblem.php?pid=5963

Make complaints

I first saw this question, eh? ? game theory? Still on the tree? I don't seem to be. . . But if you think about someone, this should not be too difficult, it may be regular

analysis

So I began to think carefully about the rules from the sample . The first sample should not be seen, but the second content is more abundant. But I still didn't find anything after simulating the second example, is it really necessary to build a line tree or something? ? Then I put the focus on the output, there are only two kinds of output, should there be some kind of parity? It is still necessary to consider the situation of the chain first, because traversing from a point on the unrooted tree is equivalent to walking a few chains (it seems that most of the problems of the tree are related to the chain). Let's simulate the following.

First, we must pay attention to the hint in the title. Every time we need to find a point with a weight of 1 on the parent node. This shows the limitation of this problem, and it will always end. Let's not consider the modification first. If you take 1 as the root, it is not difficult to see that the girl will win. One of the ways is, of



course, there are other ways , but the girl always wins.
What if 2 is taken as the root? It is not difficult to find out whether the girl wins, one of which is:



So is the girl winning when the number of edges with an edge weight of 1 in the figure is even? Still taking 2 as the root, we are followed by another node after 4.

You will find that girls still win this way.
What about this node after root node 2?

At this time, if you go to the simulation, you will find that the boy won. So we guess that it is not the number of edges with the edge weight of 1 in the figure, but the number of edges with the edge weight of 1 around the root node. Based on this bold guess, I wrote the following code, which seems to be white Wrote an edge-adding function . If you go to use the sample test and find that it is right, so I handed it in excitedly, WA

#include<cstdio>
#include<cstring>
using namespace std;
const int N=4e4+10;
struct Edge{
    int to,nxt,val;
}e[N<<1];
int Head[N],len;
void Ins(int a,int b,int c){
    e[++len].to=b;e[len].val=c;
    e[len].nxt=Head[a];Head[a]=len;
}
int cnt[N];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<n;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            cnt[a]+=c;
            cnt[b]+=c;
        }
        for(int i=1;i<=m;i++){
            int op,x,y,z;
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d",&x,&y,&z);
                if(z==1)cnt[x]++,cnt[y]++;
                else cnt[x]--,cnt[y]--;
            }
            else {
                scanf("%d",&x);
                if(cnt&1)printf("Girls win!\n");
                else printf("Boys win!\n");
            }
        }
    }
}

Secondary analysis

Since this code has passed the sample, it shows that it should not be accidental, so it should be something I haven't considered. I went back to read a side question and found that the question did not say that when \ (op == 1 \) , the weight of the transformation is equal to the original weight, that is to say, if I change 1 to 0 every time, Becomes 1, then my code above is OK, which is the sample case, but the problem is that it may be 1 becomes 1 and 0 becomes 0, so every time you must scan the sum of the edge weights around a root , Which is the code below.

#include<cstdio>
#include<cstring>
using namespace std;
const int N=4e4+10;
struct Edge{
    int to,nxt,val;
}e[N<<1];
int Head[N],len;
void Ins(int a,int b,int c){
    e[++len].to=b;e[len].val=c;
    e[len].nxt=Head[a];Head[a]=len;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        memset(Head,0,sizeof(Head));
        len=0;
        for(int i=1;i<n;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            Ins(a,b,c);Ins(b,a,c);
        }
        for(int i=1;i<=m;i++){
            int op,x,y,z;
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d",&x,&y,&z);
                for(int i=Head[x];i;i=e[i].nxt)
                    if(e[i].to==y)e[i].val=z;
                for(int i=Head[y];i;i=e[i].nxt)
                    if(e[i].to==x)e[i].val=z;
            }
            else {
                int cnt=0;
                scanf("%d",&x);
                for(int i=Head[x];i;i=e[i].nxt)cnt+=e[i].val;
                if(cnt&1)printf("Girls win!\n");
                else printf("Boys win!\n");
            }
        }
    }
}

prove

It's not very good to feel like this after writing, and it's embarrassing if you guess wrong, so I want to prove it.
In order to simplify the problem, we only need to prove the situation of the chain. If the weight of the edge connected to the root node is 1, there are two cases for the remaining edges, one is all 1, and the other is 0, discuss separately.
If it contains 0,

it is because the girl chooses points arbitrarily, so let the girl choose the last point, so that the edge connecting the root node will be set to 0, and because it contains 0, there will definitely be left the edge weight of 1. At this time, because the boys have to transform the edges, they will definitely transform the weight value to 1, because the root node is 0 when the boys transform, so in this case, it is only possible that the girl makes the root node become 0, that is, only Girls will win.
What if it doesn't contain 0? That girl can make the boy change at one time, and the girl still wins.
When the weight value of the edge connecting the root node is 0, it will be reversed, and the proof is completed.

Guess you like

Origin www.cnblogs.com/anyixing-fly/p/12682500.html