拓扑排序应用基础
具体见书P95。
给定一个N个点,M条边的有向无环图,问每个点直接或间接可到达的点的数量。
书中有详细介绍,这里就不再赘述了。
简而言之就是拓扑排序+状态压缩 。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<bitset>
#include<vector>
#include<queue>
#define N 30030
#define M 30030
using namespace std;
int n,m,f[N],side[N];
int head[N],cnt=0;
struct node{
int to,next;
}edge[M];
vector<int>path;
bitset<M>b[N];
queue<int>q;
void addedge(int x,int y){
cnt++;
edge[cnt].next=head[x];
edge[cnt].to=y;、
head[x]=cnt;
return;
}
void topo(){
for(int i=1;i<=n;i++){
if(!side[i]) q.push(i)
}
while(!q.empty()){
int now=q.front();
q.pop();
path.push_back(now);
for(int i=head[now];i;i=edge[i].next){
int y=edge[i].to;
if(!--side[y]) q.push(y);
}
}
return;
}
int main(){
memset(side,0,sizeof(side));
scanf("%d %d",&n,&m);
int u,v;
for(int i=1;i<=m;i++){
scanf("%d %d",&u,&v);
addedge(u,v);
side[v]++;
}
topo();
for(int i=path.size()-1;i>=0;i--){
int u=path[i];
b[u][u]=1;
for(int j=head[u];j;j=edge[j].next){
int v=edge[j].to;
b[u]|=b[v];
}
}
for(int i=1;i<=n;i++){
printf("%d\n",b[i].count());
}
return 0;
}
(逃…
原文:https://www.cnblogs.com/lpf-666/p/12435977.html