Codeforces1036G Sources and Sinks 【构造】【状态压缩】

题目分析:

考虑一个源点集合$S$,如果$S$能到的点$T$比$S$小,那么$T$全连到$S$里面,其它点就到不了$T$啦。否则我们全连完后$S$集合被迫扩大,所以总能扩大满。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 1002000;
 5 
 6 int n,m,in[maxn],f[maxn],nb[maxn],Num;
 7 vector <int> g[maxn];
 8 int forw[maxn],flag;
 9 
10 void dfs(int now){
11     if(g[now].size() == 0) f[now] = (1<<nb[now]-1);
12     for(int i=0;i<g[now].size();i++){
13     if(!f[g[now][i]]) dfs(g[now][i]);
14     f[now] |= f[g[now][i]];
15     }
16 }
17 
18 void read(){
19     scanf("%d%d",&n,&m);
20     for(int i=1;i<=m;i++){
21     int u,v; scanf("%d%d",&u,&v);
22     g[u].push_back(v);
23     in[v] ++;
24     }
25     for(int i=1;i<=n;i++) if(!g[i].size()) nb[i] = ++Num;
26     Num = 0;
27     for(int i=1;i<=n;i++) if(!in[i]) dfs(i),forw[++Num]=f[i];
28 }
29 
30 void dfs(int now,int cho,int dt){
31     if(now > Num){
32     if(cho == Num) return;
33     if(cho == 0) return;
34     if(__builtin_popcount(dt) <= cho)flag = 1;
35     }else{
36     dfs(now+1,cho,dt);
37     dfs(now+1,cho+1,dt|forw[now]);
38     }
39 }
40 
41 void work(){
42     dfs(1,0,0);
43     if(flag){puts("NO");}
44     else puts("YES");
45 }
46 
47 int main(){
48     read();
49     work();
50     return 0;
51 }

 

转载于:https://www.cnblogs.com/Menhera/p/9626446.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值