[BZOJ4478] [Jsoi2013]侦探jyy
来源:互联网 发布:北京大学网络公开课 编辑:程序博客网 时间:2024/04/27 02:41
[Jsoi2013]侦探jyy
Description
JSOI 的世界里一共有 N 个不同的事件( 依次由 1 到 N 编号),以及 M 条线索。
每一条线索对应一个二元组(x,y),表示事件 x 发生会导致事件 y 发生——注
意: 线索是单向的,也就是如果 y 发生了,并不代表 x 一定会发生。
线索是有传递性的, 即如果存在线索(x,y)以及(y,z), 那么 x 发生则会导致 z
发生。
同时由于世界是合理的,任意一个事件 x 一定不会通过某些线索导致事件 x
本身发生。
另外,整个世界仅包含这 M 条线索, 我们不认为一些事件会凭空发生(就
像福尔摩斯永远不会认为诡异的凶杀案是源于神的谴责)。具体而言: 对于某
个事件 x, 如果 x 发生了,并且存在某个事件可能导致 x 发生,那么一定至少有
一个可能导致 x 发生的事件发生了。
现在已知世界上的 M 条线索,以及 D 个已经发生的事件,那么由此推断,
哪些事件一定已经发生了呢?
Input
第一行包含用空格隔开的三个整数,分别为 N, M 和 D。
接下来 M 行,每行两个整数 x, y 表示线索(x,y), 满足 1 < = x, y < = N。
接下来 D 行为 D 个 1 到 N 之间不同的整数, 表示已知的已经发生的事件。
1 < = D < = N < = 1000, 1 < = M < = 100000
Output
包含一行至少 D 个由空格隔开的严格递增的正整数, 表示根据 M条线索以及 D 个已知事件
JYY 所能推断出的一定发生了的事件。
Sample Input
3 2 1
1 3
2 3
3
Sample Output
3
在第一个样例中,由于事件 1 和事件 2 这两个事件中的任何一个发生都会导致事件 3 发生,所以我们并不能确定到底哪个事件发生了。
在第二个样例中,由于事件 4 发生了,所以事件 2 和事件 3 中至少有一个发生了。而不论哪一个发生了,都可以推出事件 1 发生了。最终由于事件 1 发生了,使得我们可以推断出,所有 4 个事件都必然发生了。
Solution
枚举每一个事件,假设它不发生,那么它所有的前驱都不可能发生,在这种情况下我们贪心地让尽可能多的目前仍然能发生的初始事件(入度为0的事件)都发生,从而推得它们的后继都发生,此时我们再检查已知的那些点,假如已知的那些点仍然不能发生,那说明当前枚举的事件必然发生,因为当前事件不发生无法满足已知。
Code
#include <bits/stdc++.h>using namespace std;#define MS(_) memset(_,0,sizeof(_))template<typename T> inline void read(T &x){ x=0; T f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} x*=f;}const int N=1100;const int M=100100;struct Node{int v;Node *nxt;}pool[M<<1],*tail=pool,*g[N],*fa[N];int n,m,d,know[N],p0[N],p1[N],q[N],cnt=0,ans[N];inline void addedge(int u,int v){ tail->v=v;tail->nxt=g[u];g[u]=tail++; tail->v=u;tail->nxt=fa[v];fa[v]=tail++;}int main(){ read(n);read(m);read(d); for(int i=1;i<=m;i++){ int u,v; read(u);read(v);addedge(u,v); } for(int i=1;i<=d;i++){ int u; read(u);know[u]=1; } for(int i=1;i<=n;i++) if (!know[i]){ MS(p0);MS(p1);int l,r,now; for(p0[q[l=r=1]=i]=1;l<=r;l++) for(Node *p=fa[q[l]];p;p=p->nxt) if (!p0[p->v]) p0[q[++r]=p->v]=1; for(int j=1;j<=n;j++) if (!fa[j]&&!p0[j]){ for(p1[q[l=r=1]=j]=1;l<=r;l++) for(Node *p=g[q[l]];p;p=p->nxt) if (!p1[p->v]) p1[q[++r]=p->v]=1; } bool f=false; for(int j=1;j<=n&&!f;j++) if (know[j]&&!p1[j]) f=true; if(f) ans[++cnt]=i; }else ans[++cnt]=i; for(int i=1;i<cnt;i++) printf("%d ",ans[i]);printf("%d\n",ans[cnt]); return 0;}
- [BZOJ4478] [Jsoi2013]侦探jyy
- bzoj 4479: [Jsoi2013]吃货jyy
- 4480: [Jsoi2013]快乐的jyy
- bzoj 4480: [Jsoi2013]快乐的jyy
- JSOI2013 密码
- 快乐的JYY
- 致侦探!
- 侦探推理
- 侦探推理
- JSOI2013编程作业
- [BZOJ4467] [JSOI2013]数字理论
- JZOJ 3158 【JSOI2013】丢番图
- JZOJ 3158. 【JSOI2013】丢番图
- BZOJ 4459: [Jsoi2013]丢番图
- bzoj4459 [Jsoi2013]丢番图
- JSOI2013 旅行时的困惑
- bzoj 4459: [Jsoi2013]丢番图 数学
- [数学] BZOJ 4459 [Jsoi2013]丢番图
- java实现图的最小生成树(森林)MST克鲁斯卡尔(Kruskal)算法
- 2016年2月14日iOS钥匙串证书的签发者无效
- Android中Looper讲解
- hdu4289
- MapReduce:详解Shuffle过程
- [BZOJ4478] [Jsoi2013]侦探jyy
- css position属性的理解 文档流中位置与实际位置的不同
- SQL语句 SELECT LIKE like用法详解
- 单链表的插入删除
- kafka学习(四)--java开发(基于kafka0.9、1.0版本)
- 大数据工程师:大数据的java基础 第十周
- 【Android自定义View】测量和绘制浅析
- CentOS6.4下Mysql数据库的安装与配置
- LI横向样式定义