zoukankan      html  css  js  c++  java
  • bzoj 4484 [Jsoi2015]最小表示——bitset

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4484

    每个点上存一下它到每个点的连通性。用 bitset 的话空间就是 ( frac{n^2}{8} ) 左右。

    按拓扑序从大到小枚举每个点。对于每个点判断它的哪些出边能删。然后就不太会了。

    其实它的出边也不是都是等价的。连向 “拓扑序较小的点” 的出边价值更高。因为能删边的情况是 u->x->v && u->v 。

    所以按指向的点拓扑序递增的顺序枚举出边,用 bitset 看看加上这条边对于连通性有无影响即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<bitset>
    #include<queue>
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    const int N=3e4+5,M=1e5+5;
    int n,m,hd[N],xnt,to[M],nxt[M],dg[N],tot,a[N],dfn[N],tp[N];
    bitset<N> dp[N],tmp;
    queue<int> q;
    bool cmp(int u,int v){return dfn[u]<dfn[v];}
    void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;dg[y]++;}
    int main()
    {
      n=rdn();m=rdn();
      for(int i=1,u,v;i<=m;i++)
        u=rdn(),v=rdn(),add(u,v);
      for(int i=1;i<=n;i++)if(!dg[i])q.push(i);
      while(q.size())
        {
          int k=q.front(); q.pop();
          dfn[k]=++tot; a[tot]=k;
          for(int i=hd[k],v;i;i=nxt[i])
        if(--dg[v=to[i]]==0)q.push(v);
        }
      int ans=0;
      for(int i=n;i;i--)
        {
          int cr=a[i],p=0;
          for(int j=hd[cr];j;j=nxt[j])
        tp[++p]=to[j];
          sort(tp+1,tp+p+1,cmp);
          for(int j=1;j<=p;j++)
        {
          int v=tp[j];
          if((dp[cr]|dp[v])==dp[cr])ans++;
          else dp[cr]|=dp[v];
        }
          dp[cr][cr]=1;//
        }
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    移动采编app
    分布式自动化测试
    appium --log-timestamp > appium.log
    处理安卓的弹窗
    Sublime text3修改tab键为缩进为四个空格
    安卓自动化测试——rf
    敏捷软件开发
    photoshop怎么旋转图片
    thinkPHP5.0模型实现软删除
    thinkPHP5.0数据查询表达式生成技巧
  • 原文地址:https://www.cnblogs.com/Narh/p/10386068.html
Copyright © 2011-2022 走看看