zoukankan      html  css  js  c++  java
  • BZOJ1315 : Ural1557Network Attack

    找到一棵dfs搜索树,给每条非树边一个随机非0权值,每条树边为所有经过它的树边的权值的异或。

    那么有2种情况是合法的:

    1.一条边权值为0,一条边权值非0。

    2.两条边异或和为0。

    排序后统计即可,时间复杂度$O(mlog m)$。

    #include<cstdio>
    #include<algorithm>
    const int N=2010,M=100010;
    int n,m,i,j,e[M][2],g[N],v[M<<1],w[M<<1],nxt[M<<1],ed,d[N],dfn,f[N],c0,c1;
    unsigned long long seed,h[M],tag[N],ans;
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
    void dfs(int x){
      d[x]=++dfn;
      for(int i=g[x];i;i=nxt[i])if(w[i]!=f[x]){
        int y=v[i];
        if(d[y]&&d[y]<=d[x]){
          for(seed=seed*233+17;!seed;seed=seed*233+17);
          h[w[i]]=seed,tag[x]^=seed,tag[y]^=seed;
        }else if(!d[y])f[y]=w[i],dfs(y);
      }
    }
    void cal(int x){
      for(int i=g[x];i;i=nxt[i])if(f[v[i]]==w[i]&&d[v[i]]>d[x])cal(v[i]),tag[x]^=tag[v[i]];
      h[f[x]]=tag[x];
    }
    int main(){
      read(n),read(m);
      for(i=1;i<=m;i++)read(e[i][0]),read(e[i][1]),add(e[i][0],e[i][1],i),add(e[i][1],e[i][0],i);
      dfs(1),cal(1);
      for(i=1;i<=m;i++)if(h[i])c1++;else c0++;
      ans=1ULL*c0*c1;
      std::sort(h+1,h+m+1);
      for(i=1;i<=m;i=j){
        for(j=i;j<=m&&h[i]==h[j];j++);
        ans+=1ULL*(j-i)*(j-i-1)/2;
      }
      return printf("%llu",ans),0;
    }
    

      

  • 相关阅读:
    __attribute__ 总结
    linux文件夹打包命令
    学习ARM的一些基本知识,个人整理
    备忘录之 —— .bashrc(IC工具篇)
    GitHub的基本使用
    02: SocketServer服务
    01: socket模块
    08: python基础练习题
    07: 高阶函数&异常处理
    06: 面向对象
  • 原文地址:https://www.cnblogs.com/clrs97/p/5253858.html
Copyright © 2011-2022 走看看