http://codeforces.com/gym/101128

题目大意:给你一个a,b,e,p。有e个点,p条有向边,每条边为(x,y),表示x->y,每次我们都取出一个入度为0的,并且一次性取出来的个数为a(或b)。当然,取出来的种类可能有很多种(即一个集合),问,这个集合中有多少个数字是相同的。

第一个输出集合长度为a的,第二个输出集合长度为b的,第三个输出无论如何都无法被取出的个数。

思路:建立正向图和反向图。

定义pair<int, int> interval[i] 表示第i个节点能在[L, R]的任意步走到,L表示first,R表示second

首先for(0~e),暴力目前节点是i

然后我们向上dfs一次,表示走到当前节点至少需要几步。这个就是左端点

然后我们再从上到下进行bfs,每次如果能走,那么step就++,

然后无法bfs了,就是最终的step,就是右端点
然后就是最后的三个判断了

if (interval[i].se <= a) ans1++;
if (interval[i].se <= b) ans2++;
if (interval[i].fi > b) ans3++;

orz,想了3个小时(刚开始以为可能存在环,所以还特地写了强连通,后来发现,去掉强连通了也AC了,一口老血)

跑了960ms

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = + ;
int a , b , e , p;
vector<int> edge[maxn];
vector<int> disedge[maxn];///反向
int in[maxn], tmpin[maxn];
vector<int> zero;
int step;
bool vis[maxn], can[maxn];
int cnt[maxn];
pair<int, int> interval[maxn]; void dfs(int u){
vis[u] = true;
step++;
for (int i = ; i < disedge[u].size(); i++){
int v = disedge[u][i];
if (vis[v]) continue;
dfs(v);
}
} void solve(){
for (int i = ; i < e; i++){
step = ;
for (int j = ; j < e; j++) vis[j] = false, tmpin[j] = in[j];
vis[i] = true;
for (int j = ; j < disedge[i].size(); j++){
int v = disedge[i][j];
if (!vis[v]) dfs(v);
}
interval[i].fi = step;
queue<int> que;
for (int j = ; j < zero.size(); j++){
if(zero[j] != i) que.push(zero[j]);
}
while (!que.empty()){
queue<int> tmp;
while (!que.empty()){
int pos = que.front(); que.pop();
if (!vis[pos]) step++;
for (int j = ; j < edge[pos].size(); j++){
int v = edge[pos][j];
if (v == i) continue;
tmpin[v]--;
if (tmpin[v] == ) tmp.push(v);
}
}
que = tmp;
}
interval[i].se = step;
}
int ans1 = , ans2 = , ans3 = ;
for (int i = ; i < e; i++){
if (interval[i].se <= a) ans1++;
if (interval[i].se <= b) ans2++;
if (interval[i].fi > b) ans3++;
}
printf("%d\n%d\n%d\n", ans1, ans2, ans3);
} int main(){
while (scanf("%d%d%d%d", &a, &b, &e, &p) == ){
zero.clear();
for (int i = ; i < e; i++) {
in[i] = , can[i] = true;
edge[i].clear(), disedge[i].clear();
}
for(int i = ; i < p ; ++ i){
int u, v;
scanf("%d%d" , &u , &v);
edge[u].push_back(v);
disedge[v].push_back(u);
in[v]++;
}
for (int i = ; i < e; i++){
if (in[i] == ) zero.push_back(i);
}
solve();
}
return ;
}

看了一下大佬的想法,果然是我比较zz:大佬的链接

对于第一个输出和第二个输出,他们的右端点就是n-num[i],其中num[i]表示i节点所支配的节点的个数,当n-num[i] <= x的时候,i节点必然选择。

然后对于第三种的话,定义他是节点i,那么我们就是看看节点i什么时候“解封”(即可以选择),那么我们对于所有的能到节点i的节点的num都加在一起(建立反向图即可),那么所有的num和如果大于b,就++即可

很好的脑洞题:dfs+暴力 Gym - 101128A Promotions的更多相关文章

  1. Gym 101128A Promotions(思维 + dfs)题解

    题意:给一有向图,如果A指向B,则A是B的上级.一直i要升职那么他的上级必须都升职.现在给你一个升职人数的区间[a, b],问你升职a人时几个人必被升职,b时几个人必升职,b时几个人没有可能被升职. ...

  2. 【拓扑排序】【bitset】Gym - 101128A - Promotions

    给你一张DAG,若选择u点,则必须先选择所有能到达其的点.问你在选择A个点的情况下,哪些点必选:选择B个点的情况下,哪些点必选:选择B个点的情况下,哪些点一定不选. 选择A个点的情况,必选的点是那些其 ...

  3. ACM: Gym 100935G Board Game - DFS暴力搜索

    Board Game Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u  Gym 100 ...

  4. hdu 1010 Tempter of the Bone(dfs暴力)

    Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, ...

  5. ACM: FZU 2107 Hua Rong Dao - DFS - 暴力

    FZU 2107 Hua Rong Dao Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I6 ...

  6. 图论(KM算法,脑洞题):HNOI 2014 画框(frame)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABPoAAANFCAIAAABtIwXVAAAgAElEQVR4nOydeVxTV/r/n9ertaJEC4

  7. LeetCode刷题 DFS+回溯

    一.DFS介绍 二.LeetCode 实战 LC 17. 电话号码的字母组合 解法思路 解题步骤 代码 LC 79. 单词搜索 解题思路 解题步骤 代码 LC 46. 全排列 解题思路一 解题步骤 代 ...

  8. hdu 5612 Baby Ming and Matrix games(dfs暴力)

    Problem Description These few days, Baby Ming is addicted to playing a matrix game. Given a n∗m matr ...

  9. 一道很经典的 BFS 题

    一道很经典的 BFS 题 想认真的写篇题解. 题目来自:https://www.luogu.org/problemnew/show/P1126 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运 ...

随机推荐

  1. JS 操作 checkbox(cc角色管理等)

    1.获取选中的权限的个数 var size=$("input[name='privileges']:checked").size();

  2. c# webBrowser打开pdf问题

    1.生成模式使用release加*86尝试,使用debug则webBrowser不生效

  3. 第二次c++作业(觉得渐渐入门系列)

    其实说实话,我还是不敢很确定地说面向对象和面向过程这两种语言,我确实能分得开,但是我觉得倒是比以前好很多了.//(大概是谈了对象,知道了什么是面向对象编程) 1.从个人角度来说, a:面向过程就是-- ...

  4. 福大软工·第十一次作业-Alpha事后诸葛亮

    福大软工·第十一次作业-Alpha事后诸葛亮 组长博客链接 本次作业博客链接 项目Postmortem 模板 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描 ...

  5. 自签证书 doesn't match any of the subject alternative names

    出现这个的原因是https中的域名或者IP,与证书中登记的不一致. 如果是自签证书的话,可以根据具体需要重新生成证书. 还有一种解决方案是在java中跳过这个检查. 绕过检查分两类,一个是绕过证书在C ...

  6. 【Linux】- 对find,xargs,grep和管道的一些理解

    问题 相信大家都知道在目录中搜索含有固定字符串文件的命令: find . -name '*.py' |xargs grep test 刚开始的时候,我不熟悉xargs命令,所以直接使用的命令是: fi ...

  7. C# 事件总线 EventBus

    1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉.事件总线是对发布-订阅模式的一种实现.它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需 ...

  8. PHP执行原理

    简单解释:PHP执行原理 客户端向服务器发送一个请求,如果请求的是一个HTML页面,服务器直接将HTML页面发送到客户端给浏览器解析,如果请求的是PHP页面,则服务器会运行PHP页面然后生成标准的HT ...

  9. apache常用的两种工作模式 prefork和worker

    apache作为现今web服务器用的最广泛也是最稳定的开源服务器软件,其工作模式有许多中,目前主要有两种模式:prefork模式和worker模式 一.两种模式 prefork模式: prefork是 ...

  10. 从装饰者模式的理解说JAVA的IO包

    1. 装饰者模式的详解 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性 的替代方案. 装饰者模式设计类之间的关系: 其 中Component是一个超类,ConcreteC ...