zoukankan      html  css  js  c++  java
  • BZOJ2948 : [Poi2001]绿色游戏

    维护一个保护集合$S$,表示哪些点$A$可能胜利。

    首先将所有绿点加入$S$。

    $1.$对于一个不在$S$的$A$点,若它存在某个后继在$S$中,则将其加入$S$。

    $2.$对于一个不在$S$的$B$点,若它所有后继都在$S$中,则将其加入$S$。

    通过拓扑可以$O(n+m)$求出$S$集合,那么剩下的点$A$必败。

    $1.$对于一个在$S$的$A$点,若它所有后继都不在$S$中,则将其从$S$中移除。

    $2.$对于一个在$S$的$B$点,若它存在某个后继不在$S$中,则将其从$S$中移除。

    同样可以通过拓扑$O(n+m)$求出最终的$S$集合。

    这样会导致某些绿点不在$S$中,那么它们就失去了作为绿点的价值,将其标记为白点。

    重复运行这个算法$O(n)$轮直到所有绿点都发挥了价值,此时$S$中的点$A$必胜。

    时间复杂度$O(n(n+m))$。

    #include<cstdio>
    const int N=3010,M=30010;
    int n,m,i,j,x,c[N],d[N],g[N],v[M],nxt[M],ed,q[N],vis[N],deg[N],cnt;
    inline void add(int x,int y){d[v[++ed]=x]++;nxt[ed]=g[y];g[y]=ed;}
    bool solve(){
      int i,x,h=1,t=0;
      for(i=1;i<=n;i++){
        vis[i]=c[i],deg[i]=d[i];
        if(vis[i])q[++t]=i;
      }
      while(h<=t)for(i=g[q[h++]];i;i=nxt[i])if(!vis[x=v[i]])
        if(x<=m)vis[q[++t]=x]=1;
        else if(!(--deg[x]))vis[q[++t]=x]=1;
      for(i=h=1,t=0;i<=n;i++){
        deg[i]=d[i];
        if(!vis[i])q[++t]=i;
      }
      while(h<=t)for(i=g[q[h++]];i;i=nxt[i])if(vis[x=v[i]])
        if(x>m)vis[q[++t]=x]=0;
        else if(!(--deg[x]))vis[q[++t]=x]=0;
      for(t=0,i=1;i<=n;i++)if(c[i]&&!vis[i])c[i]=0,t=1;
      return t;
    }
    int main(){
      scanf("%d%d",&m,&n);n+=m;
      for(i=1;i<=n;i++)for(scanf("%d%d",&c[i],&j);j--;add(i,x))scanf("%d",&x);
      while(solve());
      for(i=1;i<=n;i++)if(vis[i])q[++cnt]=i;
      for(printf("%d
    ",cnt),i=1;i<=cnt;i++)printf("%d
    ",q[i]);
      return 0;
    }
    

      

  • 相关阅读:
    UIScrollView 截图
    cocoapods import 第三方 自动补全
    UIWebView内存泄露问题解决方法
    iOS常用小控件集合
    UIViewController视图控制器视图的生命周期
    UIView
    UITextField
    UITabBar UITabBarController
    iOS图片相似度比较
    iOS获取已安装的app列表(私有库)+ 通过包名打开应用
  • 原文地址:https://www.cnblogs.com/clrs97/p/7378075.html
Copyright © 2011-2022 走看看