串行调度(serial)
除等价条件, 根据题意设置限制条件,然后求字典序最小拓扑序。
简洁版
#include<bits/stdc++.h> using namespace std; const int N=2e4+5; const int M=2e4+5; const int E=8e5+5; template <typename T> inline void read(T &x){ T f=1;char ch=getchar();x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} x*=f; } vector<int>lastR[N];int lastW[N]; bitset<M>d[M]; int n,m,pcnt,qcnt,tot,ind[M],to[E],nxt[E],head[M]; inline void add(int x,int y){ if(!x||x==y) return ; ind[y]++; to[++tot]=y;nxt[tot]=head[x];head[x]=tot; } inline void init(){ read(n);read(m);read(pcnt);read(qcnt); for(int i=1,op,xk,tk;i<=pcnt;i++){ read(op);read(xk);read(tk); if(op){ if(!lastR[xk].empty()){ for(auto &i:lastR[xk]) add(i,tk); lastR[xk].clear(); } else{ add(lastW[xk],tk); } lastW[xk]=tk; } else{ add(lastW[xk],tk); lastR[xk].push_back(tk); } } } priority_queue<int,vector<int>,greater<int> >q; inline void topo(){ d[0]=1; for(int i=1;i<=m;i++) d[i]=d[i-1]<<1; for(int i=1;i<=m;i++) if(!ind[i]) q.push(i); for(int i=1;i<=m;i++){ int x=q.top();q.pop(); printf("%d ",x); for(int j=head[x];j;j=nxt[j]){ if(!--ind[to[j]]){ q.push(to[j]); } d[to[j]]|=d[x]; } } puts(""); for(int i=qcnt,x,y;i;i--){ read(x);read(y); puts(!d[x].test(y)?"YES":"NO"); } } int main(){ init(); topo(); return 0; }
纯手写bitset
#include<queue> #include<vector> #include<cstdio> using std::vector; using std::priority_queue; const int N=2e4+5; const int M=2e4+5; const int E=8e5+5; template <typename T> inline void read(T &x){ T f=1;char ch=getchar();x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} x*=f; } vector<int>lastR[N];int lastW[N]; struct BitSet{//模拟bitset // unsigned int 以压缩32位 // unsigned long long 可以压缩64位 const static int N = M / 32 + 5; unsigned data[N]; unsigned& operator[](int a){ return data[a]; } const unsigned& operator[](int a)const{ return data[a]; } bool get(int a){ return (data[a >> 5] >> (a & 31)) & 1; } void set(int a){ data[a >> 5] |= 1 << (a & 31); } void unset(int a){ data[a >> 5] &= ~(1 << (a & 31)); } BitSet& operator|=(const BitSet& a){ for(int i = 0; i < N; i++) data[i] |= a[i]; return *this; } }used[M]; int n,m,pcnt,qcnt,tot,ind[M],to[E],nxt[E],head[M]; inline void add(int x,int y){ if(!x||x==y) return ; ind[y]++; to[++tot]=y;nxt[tot]=head[x];head[x]=tot; } inline void init(){ read(n);read(m);read(pcnt);read(qcnt); for(int i=1,op,xk,tk;i<=pcnt;i++){ read(op);read(xk);read(tk); if(op){ if(!lastR[xk].empty()){ for(auto &i:lastR[xk]) add(i,tk); lastR[xk].clear(); } else{ add(lastW[xk],tk); } lastW[xk]=tk; } else{ add(lastW[xk],tk); lastR[xk].push_back(tk); } } } priority_queue<int,vector<int>,std::greater<int> >q; inline void topo(){ for(int i=1;i<=m;i++) used[i].set(i); for(int i=1;i<=m;i++) if(!ind[i]) q.push(i); for(int i=1;i<=m;i++){ int x=q.top();q.pop(); printf("%d ",x); for(int j=head[x];j;j=nxt[j]){ if(!--ind[to[j]]){ q.push(to[j]); } used[to[j]]|=used[x]; } } puts(""); for(int i=qcnt,x,y;i;i--){ read(x);read(y); puts(!used[x].get(y)?"YES":"NO"); } } int main(){ init(); topo(); return 0; }