zoukankan      html  css  js  c++  java
  • 10.28T6 动态维护最小生成树

    5163 -- 【11.04题目】玩游戏

    Description

      小A得了忧郁综合症,小B正在想办法开导她。
      机智的小B决定陪着小A玩游戏,他从魔法的世界里变出一张无向联通图,每条边上都有边权。小B定义一条路径的权值为所有经过边中的最大权值,小A则定义两点的最短路径为所有路径中权值最小的路径权。
      每次小A先选出两个点m1,m2,然后小B选出两个点b1,b2,计算出它们的最短路径m,b,然后小B会拿出两堆灵魂宝石,一堆有m个,另一堆有b个。然后小A先从一堆中选出若干个灵魂宝石拿走,接下来小B重复同样的操作,如此反复,直到取走最后一颗灵魂宝石,然后取走最后一颗宝石的人获胜。
      小B认为这样游戏太简单,于是他会不定期向这张图上加上一些边,以增大游戏难度。
      小A具有预知未来的能力,她看到了自己和小B在未来游戏中的选择,以及小B增加的边。现在对于每次游戏,小A想知道自己是否存在必胜的方法。但是预知未来已经消耗了她太多精力,出于疲惫她只好找到了你。

    Input

      第一行两个数N和M,表示这张无向图初始的点数与边数;
      接下来M行,每行三个数u,v,q,表示点u和点v之间存在一条权值为q的边;
      接下来一行一个数Q,表示操作总数;
      接下来Q行,表示操作,每行格式为下面两条中的一条:
      1.add u v q:表示在u与v之间加上一条边权为q的边;
      2.game m1 m2 b1 b2:表示一次游戏,其中小A的选择点m1,m2,小B的选择点b1,b2。
      数据保证1≤u,v,m1,m2,b1,b2≤n,1≤q,m1≠m2 且 b1≠b2

    Output

      对于每个game输出一行,若小A存在必胜策略,则输出“madoka”,否则输出“Baozika”,以回车结尾

    Sample Input

    5 6 1 2 3 2 3 6 4 2 4 5 3 5 3 4 5 5 1 5 4 game 1 3 4 3 game 1 5 2 4 add 2 5 4 game 1 5 3 4

    Sample Output

    Baozika madoka madoka

    Hint




     
     
     
    我们先求出一个最小生成树,然后每加上一条边我们就重新dfs一遍维护
    至于那个博弈实际上就是一个nim博弈,直接异或起来判断是否是0就可以了
    code:
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<string>
      6 #define N 500005
      7 using namespace std;
      8 long long n,m;
      9 struct node {
     10     long long u,v,w,used;
     11 } e[N],t[N];
     12 int first[N],nxt[N],cnt;
     13 inline void add(long long u,long long v,long long w,long long d) {
     14     e[++cnt].u=u;
     15     e[cnt].v=v;
     16     e[cnt].w=w;
     17     e[cnt].used=d;
     18     nxt[cnt]=first[u];
     19     first[u]=cnt;
     20 }
     21 inline bool cmp(const node&a,const node&b) {
     22     return a.w<b.w;
     23 }
     24 long long fa[N];
     25 inline long long find(long long x) {
     26     if(x!=fa[x])return fa[x]=find(fa[x]);
     27     return fa[x];
     28 }
     29 inline void merge(long long x,long long y) {
     30     long long f1=find(x),f2=find(y);
     31     if(f1!=f2) {
     32         fa[f1]=f2;
     33     }
     34 }
     35 inline void kruskal() {
     36     long long cnt_=0;
     37     for(long long i=1; i<=m; ++i) {
     38         long long u=t[i].u,v=t[i].v,w=t[i].w;
     39         if(find(u)!=find(v)) {
     40             merge(u,v);
     41             add(u,v,w,1);
     42             add(v,u,w,1);
     43             cnt_++;
     44             if(cnt_==n-1)return;
     45         }
     46     }
     47 }
     48 struct T {
     49     long long id,max;
     50 };
     51 long long dep[N],mx[N][30],f[N][30],bianhao[N][30];
     52 T lca(long long x,long long y) {
     53     if(dep[x]<dep[y])swap(x,y);
     54     long long id,max0=0;
     55     for(long long i=15; i>=0; i--) {
     56         if(dep[f[x][i]]>=dep[y]) {
     57             if(max0<mx[x][i]) {
     58                 max0=mx[x][i];
     59                 id=bianhao[x][i];
     60             }
     61             x=f[x][i];
     62         }
     63         if(x==y)return (T) {
     64             id,max0
     65         };
     66     }
     67     for(long long i=15; i>=0; i--) {
     68         if(f[x][i]==f[y][i])continue;
     69         if(max0<mx[x][i]) {
     70             max0=mx[x][i];
     71             id=bianhao[x][i];
     72         }
     73         if(max0<mx[y][i]) {
     74             max0=mx[y][i];
     75             id=bianhao[y][i];
     76         }
     77         x=f[x][i];
     78         y=f[y][i];
     79     }
     80     T temp;
     81     if(max0<mx[y][0]) {
     82         max0=mx[y][0];
     83         id=bianhao[y][0];
     84     }
     85     if(max0<mx[x][0]) {
     86         max0=mx[x][0];
     87         id=bianhao[x][0];
     88     }
     89     temp.id=id,temp.max=max0;
     90     return temp;
     91 }
     92 long long dis[N];
     93 inline void dfs(long long x) {
     94     for(long long i=first[x]; i; i=nxt[i]) {
     95         if(!e[i].used)continue;
     96         long long v=e[i].v;
     97         if(v==f[x][0])continue;
     98         f[v][0]=x;
     99         bianhao[v][0]=i;
    100         dep[v]=dep[x]+1;
    101         mx[v][0]=e[i].w;
    102         dfs(v);
    103     }
    104 }
    105 inline void build() {
    106     f[1][0]=1;
    107     dep[1]=0;
    108     dfs(1);
    109     for(long long i=1; i<=15; ++i) {
    110         for(long long j=1; j<=n; ++j) {
    111             f[j][i]=f[f[j][i-1]][i-1];
    112             mx[j][i]=max(mx[j][i-1],mx[f[j][i-1]][i-1]);
    113             if(mx[j][i]==mx[j][i-1])bianhao[j][i]=bianhao[j][i-1];
    114             else bianhao[j][i]=bianhao[f[j][i-1]][i-1];
    115         }
    116     }
    117 }
    118 inline long long read(){
    119     long long x=0,f=1;
    120     char c=getchar();
    121     while(!isdigit(c)){
    122         if(c=='-')f=-1;
    123         c=getchar();
    124     }
    125     while(isdigit(c)){
    126         x=(x<<3)+(x<<1)+c-'0';
    127         c=getchar();
    128     }
    129     return x*f;
    130 }
    131 int main() {
    132 //    freopen("game1.in","r",stdin);
    133     n=read(),m=read();
    134     for(long long i=1; i<=n; ++i)fa[i]=i;
    135     for(long long i=1; i<=m; ++i) {
    136         t[i].u=read(),t[i].v=read(),t[i].w=read();
    137     }
    138     sort(t+1,t+m+1,cmp);
    139     kruskal();
    140     build();
    141     //cout<<e[lca(2,5).id].u<<" "<<e[lca(2,5).id].v<<"!!!!!";
    142     long long Q;
    143     Q=read();
    144     while(Q--) {
    145         string k;
    146         cin>>k;
    147         if(k=="add") {
    148             long long u,v,w;
    149             u=read(),v=read(),w=read();
    150             T temp=lca(u,v);
    151             if(temp.max>w) {
    152                 e[temp.id].used=0;
    153 //                cout<<u<<" "<<v<<" u->"<<e[temp.id].u<<" v->"<<e[temp.id].v<<" max->"<<temp.max<<'
    ';
    154                 if(e[temp.id+1].u==e[temp.id].v&&e[temp.id+1].v==e[temp.id].u) {
    155                     e[temp.id+1].used=0;
    156                 } else e[temp.id-1].used=0;
    157                 add(u,v,w,1);
    158                 add(v,u,w,1);
    159                 build();
    160             }
    161         } else {
    162             long long a,b,c,d;
    163             a=read(),b=read(),c=read(),d=read();
    164             long long max1=lca(a,b).max,max2=lca(c,d).max;
    165 //            cout<<"max1->"<<max1<<" max2->"<<max2<<" "<<'
    ';
    166             if(max1^max2) {
    167                 cout<<"madoka"<<'
    ';
    168             } else {
    169                 cout<<"Baozika"<<'
    ';
    170             }
    171         }
    172     }
    173     return 0;
    174 }

    over

  • 相关阅读:
    C语言博客作业06--结构体&文件
    C语言博客05--指针
    C语言博客作业04--数组
    LeetCode错题集
    C博客作业--指针
    深入浅出强化学习:原理入门(待更新)
    Detectron2环境配置+Ubantu+CUDA10.1+pytorch1.7.0
    论文记载:A Survey on Traffic Signal Control Methods
    论文记载:FRAP:Learning Phase Competition for Traffic Signal Control
    周博磊老师强化学习纲领笔记第三课:无模型的价值函数估计和控制
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9867132.html
Copyright © 2011-2022 走看看