BZOJ3355: [Usaco2004 Jan]有序奶牛

很神的一道拓扑排序
http://www.cnblogs.com/clrs97/p/4790290.html

第一道bitset的题目

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<bitset>
using namespace std;

char c;
inline void read(int &a)
{a=0;
    do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int n,l;
struct Chain
{
    int u;
    Chain *next;
    Chain(){next=NULL;}
}*Head[1501],*Head2[1501];

int D[10000001];

struct A
{
    int u,v;
inline friend bool operator <(A a,A b){return a.u^b.u?a.u<b.u:a.v<b.v;}
}Q[100001];

inline void Add(int u,int v)
{
    if(u^v)
    D[v]++;
    Chain *tp=new Chain;
    tp->u=v;
    tp->next=Head[u];
    Head[u]=tp;
}

inline void Add1(int u,int v)
{
    Chain *tp=new Chain;
    tp->u=v;
    tp->next=Head2[u];
    Head2[u]=tp;
}

int ans;
inline void Add2(int u,int v)
{
    Q[++ans].u=u;
    Q[ans].v=v;
}

bitset<1501>F[1501];
int tot;
int stack[1501];
int main()
{
    int i,x,y,j,k;
    read(n),read(l);
    for(i=1;i<=n;i++)
     Add(i,i),Add1(i,i),F[i][i]=1;
    for(i=1;i<=l;i++)
    read(x),read(y),Add(x,y);
    for(i=1;i<=n;++i)
    if(!D[i]){
    stack[++tot]=i;}    
    for(i=1;tot<n;i++)
    {
        x=stack[i];
        for(Chain *tp=Head[x];tp->u!=x;Add1(tp->u,x),tp=tp->next)
          if(!--D[tp->u])
            stack[++tot]=tp->u;
    }
    Chain *tp;
    for(i=1;i<=n;i++)
     for(tp=Head2[x=stack[i]];tp->u!=x;F[x]|=F[tp->u],tp=tp->next)
      if(!F[x][tp->u])
            Add2(tp->u,x);


    sort(Q+1,Q+1+ans);
    printf("%d\n",ans);
    for(i=1;i<=ans;i++)
      printf("%d %d\n",Q[i].u,Q[i].v);
    return 0;
 } 

你可能感兴趣的:(BZOJ3355: [Usaco2004 Jan]有序奶牛)