• BZOJ3355 : [Usaco2004 Jan]有序奶牛


    对于一条边x->y,若去掉之后x不能到达y,那么它是必需的。

    首先拓扑排序求出拓扑序,然后按照终点拓扑序为第一关键字,起点拓扑序为第二关键字从小到大加边。

    对于每个点,维护一个bitset,表示当前从哪些点可以到达自己。

    时间复杂度$O(frac{nm}{32})$。

    #include<cstdio>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    typedef pair<int,int>P;
    const int N=1502,M=10002;
    int n,m,i,j,x,y,d[N],g[N],g2[N],v[M],v2[M],nxt[M],nxt2[M],ed,h,t,q[N],ans;bitset<N>f[N];P b[M];
    inline void add(int x,int y){d[y]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    inline void add2(int x,int y){v2[++ed]=y;nxt2[ed]=g2[x];g2[x]=ed;}
    int main(){
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++)f[i][i]=1;
      while(m--)scanf("%d%d",&x,&y),add(x,y);
      for(ed=0,i=h=1;i<=n;i++)if(!d[i])q[++t]=i;
      while(h<=t)for(i=g[x=q[h++]];i;add2(v[i],x),i=nxt[i])if(!(--d[v[i]]))q[++t]=v[i];
      for(i=1;i<=n;i++)for(j=g2[x=q[i]];j;f[x]|=f[v2[j]],j=nxt2[j])if(!f[x][v2[j]])b[++ans]=P(v2[j],x);
      sort(b+1,b+ans+1);
      for(printf("%d
    ",ans),i=1;i<=ans;i++)printf("%d %d
    ",b[i].first,b[i].second);
      return 0;
    }
    

      

  • 相关阅读:
    BZOJ3744 : Gty的妹子序列
    BZOJ2827 : 千山鸟飞绝
    BZOJ3547 : [ONTAK2010]Matchings
    BZOJ1185 : [HNOI2007]最小矩形覆盖
    BZOJ3046 : lagoon
    BZOJ3743 : [Coci2014]Kamp
    BZOJ3742 : Painting
    iOS移动开发周报-第25期
    适合码农工作时玩的游戏:Scrum
    iOS移动开发周报-第24期
  • 原文地址:https://www.cnblogs.com/clrs97/p/4790290.html
Copyright © 2020-2023  润新知