JZOJ.5328【NOIP2017模拟8.22】世界线

Description

 

Input

Output

 

Sample Input

5 5
1 2
1 3
2 3
3 4
4 5

Sample Output

5
 

Data Constraint

 

Hint

样例解释

先拓扑排序,从出度为0的点开始搜,连这个点的前一个点以及之前的点都要和这个点连边,这样算出每个点能到达的其他点再减去已有的边就可以了。

然而需要用bitset优化状态,然而还有可能会爆空间,我们需要分几次搜索.....

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <bitset>
 5 #define N 1300000
 6 using namespace std;
 7 bitset<1001>qwq[N];
 8 int du[N/2],n,m,head[N],next[N],to[N],num,q[N/2],t;
 9 long long ans;
10 void add(int u,int v){
11     num++;
12     next[num]=head[u];
13     to[num]=v;
14     head[u]=num;
15 }
16 int main(){
17     freopen("worldline.in","r",stdin);
18     freopen("worldline.out","w",stdout);
19     scanf("%d%d",&n,&m);
20     ans=-m;
21     num=0;
22     for (int i=1,u=0,v=0;i<=m;i++){
23         scanf("%d%d",&u,&v);
24         add(u,v);
25         du[v]++;
26     }
27     t=0;
28     for (int i=1;i<=n;i++)
29         if (!du[i]) q[++t]=i;
30     for (int v=0,i=1;i<=t;i++)
31         for (int j=head[q[i]];j;j=next[j]){
32             v=to[j];
33             du[v]--;
34             if (!du[v]) q[++t]=v;
35         }
36     for (int l=1,r=1000;l<=n;l=r+1,r+=1000){
37         for (int i=1;i<=n;i++) qwq[i].reset();
38         for (int i=t;i>=1;i--){
39             for (int j=head[q[i]];j;j=next[j]){
40                 qwq[q[i]]|=qwq[to[j]];
41             }
42             ans+=qwq[q[i]].count();
43             if ((q[i]>=l)&&q[i]<=r) qwq[q[i]][q[i]-l]=1; 
44         }
45     }
46     printf("%lld\n",ans);
47 }
神奇的代码

 

posted @ 2017-08-22 19:29  ~Lanly~  阅读(263)  评论(0编辑  收藏  举报