首先考虑怎么check一个点是否能被最后一个删除。

可以这么建图,以这个点建有根树,边全部向上指,再加上剩下的有向边。

很明显,这里的一条边的定义就变成了只有删去这个点,才可以删去它指向的点。

因此,只需要建n次图暴力判断是否有环即可。

这样做是n^2的。

考虑加入一条边后,会产生什么影响。

发现这条边会导致一些点答案直接被钦定为零(这些点满足以它们为根一定会存在环)

设边为u---->v

具体分析一下,这些点是所有以v为根建有根树后,u子树内的所有点。

这个可以通过类似换根的分类讨论的方法来找到这些点,它们构成了几段(O(1)级别)区间。

直接差分钦定它们答案为0即可。

然而这样做是有bug的。

考虑这样一个图



按照上述方法只能判断出2,3,4,5不合法。

事实上因为在上述方法中,只考虑了每条边自己单一的影响,而没有考虑它们组合起来的影响。

胡乱分析发现,它们组合起来产生的影响要么是没影响,要么就是所有点都无法被留到最后一个删除。

这样的话,只需要特判一下是否整个图的无法被留到最后一个删除即可。

可以用类似拓扑排序的方法来判断。

#include<iostream>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdlib>
#include<algorithm>
#define N 220000
#define L 200000
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline int read()
{
char ch=0;
int x=0,flag=1;
while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*flag;
}
struct edge{int to,nxt;}e[N*2],E[N*2];
int num,head[N],NUM,HEAD[N];
inline void add(int x,int y){e[++num]=(edge){y,head[x]};head[x]=num;}
inline void ADD(int X,int Y){E[++NUM]=(edge){Y,HEAD[X]};HEAD[X]=NUM;}
queue<int>q;
bool vis[N];
int times,c[N],sz[N],deg[N],deg_[N],dep[N],dfn[N],nxt[N][25];
void dfs(int x,int fa)
{
sz[x]=1;dfn[x]=++times;dep[x]=dep[fa]+1;
for(int i=head[x];i!=-1;i=e[i].nxt)
{
int to=e[i].to;
if(to==fa)continue;
dfs(to,x);sz[x]+=sz[to];nxt[to][0]=x;
}
}
int get(int x,int k){for(int i=0;i<=20;i++)if(1<<i&k)x=nxt[x][i];return x;}
int main()
{
num=NUM=-1;memset(head,-1,sizeof(head));memset(HEAD,-1,sizeof(HEAD));
int n=read(),m=read(),tot=0;
for(int i=1;i<n;i++){int x=read(),y=read();add(x,y);add(y,x);deg[x]++;deg[y]++;}
dfs(1,1);
for(int k=1;k<=20;k++)for(int i=1;i<=n;i++)nxt[i][k]=nxt[nxt[i][k-1]][k-1];
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
ADD(x,y);deg_[y]++;
int l=dfn[x],r=dfn[x]+sz[x]-1;
if(l<=dfn[y]&&dfn[y]<=r)
{
int to=get(y,dep[y]-dep[x]-1);
int pl=dfn[to],pr=dfn[to]+sz[to]-1;
c[pl]--;c[pr+1]++;c[1]++;c[n+1]--;
}
else c[l]++,c[r+1]--;
}
for(int i=1;i<=n;i++)if(deg[i]==1&&!deg_[i])q.push(i);
while(!q.empty())
{
int x=q.front();q.pop();
if(vis[x])continue;vis[x]=true;tot++;
for(int i=head[x];i!=-1;i=e[i].nxt){int to=e[i].to;deg[x]--;deg[to]--;}
for(int i=HEAD[x];i!=-1;i=E[i].nxt){int to=E[i].to;deg_[to]--;}
for(int i=head[x];i!=-1;i=e[i].nxt){int to=e[i].to;if(deg[to]==1&&!deg_[to])q.push(to);}
for(int i=HEAD[x];i!=-1;i=E[i].nxt){int to=E[i].to;if(deg[to]==1&&!deg_[to])q.push(to);}
}
if(tot<n){for(int i=1;i<=n;i++)printf("0\n");return 0;}
for(int i=1;i<=n;i++)c[i]+=c[i-1];
for(int i=1;i<=n;i++)printf("%d\n",c[dfn[i]]?0:1);
return 0;
}

P5157 [USACO18DEC]The Cow Gathering的更多相关文章

  1. [USACO18DEC]The Cow Gathering

    Description: 给定一棵树,每次删去叶子,有m个限制,分别为(a,b)表示a需要比b先删,为每个点能否成为最后被删的点 Hint: \(n,m \le 10^5\) Solution: 手模 ...

  2. [USACO18DEC]The Cow Gathering P

    首先可以思考一下每次能删去的点有什么性质. 不难发现,每次能删去的点都是入度恰好为 \(1\) 的那些点(包括 \(a_i \rightarrow b_i\) 的有向边). 换句话说,每次能删去的点既 ...

  3. BZOJ1827[USACO 2010 Mar Gold 1.Great Cow Gathering]——树形DP

    题目描述 Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 N(1<=N<=100,000) 个农场 ...

  4. 【luoguP2986】[USACO10MAR]伟大的奶牛聚集Great Cow Gathering

    题目链接 先把\(1\)作为根求每个子树的\(size\),算出把\(1\)作为集会点的代价,不难发现把集会点移动到\(u\)的儿子\(v\)上后的代价为原代价-\(v\)的\(size\)*边权+( ...

  5. P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  6. 洛谷 P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…(树规)

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  7. 洛谷 P2986 [USACO10MAR]Great Cow Gat…(树形dp+容斥原理)

    P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat… 题目描述 Bessie is planning the annual Great Cow Gathering for c ...

  8. [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  9. 【题解】Luogu p2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat 树型dp

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

随机推荐

  1. 在vim中 安装php的xdebug和 vdebug插件, 在vim中进行调试php代码

    在vim中 安装php的xdebug和 vdebug插件, 在vim中进行调试php代码 参考: http://www.cnblogs.com/qiantuwuliang/archive/2011/0 ...

  2. 振兴中华|2013年蓝桥杯A组题解析第三题-fishers

    标题: 振兴中华 小明参加了学校的趣味运动会,其中的一个项目是:跳格子. 地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg) 从我做起振 我做起振兴 做起振兴中 起振兴中华 比赛 ...

  3. TI 多模雷达1843毫米波雷达做自动泊车(用了8个雷达)

    http://e2e.ti.com/blogs_/b/behind_the_wheel/archive/2019/01/09/how-mmwave-sensors-enable-autonomous- ...

  4. Oracle用户被锁定解决方法

    解决方法: 1.用dba角色登陆:2.输入下面格式命令解锁: alter user 用户名 account unlock;3.如果密码忘记了,输入下面格式命令修改密码: alter user 用户名 ...

  5. P3833 [SHOI2012]魔法树

    思路 树剖板子 注意给出点的编号是从零开始的 代码 #include <cstdio> #include <algorithm> #include <cstring> ...

  6. 深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods)

    深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods) 2018-07-17 16:50:12 Reference:https://www.you ...

  7. 深度学习课程笔记(八)GAN 公式推导

    深度学习课程笔记(八)GAN 公式推导 2018-07-10  16:15:07

  8. ES6数字操作

    数字判断和转换 数字验证Number.isFinite( xx ) 可以使用Number.isFinite( )来进行数字验证,只要是数字,不论是浮点型还是整形都会返回true,其他时候会返回fals ...

  9. Latex: "Missing $ inserted" 解决方法

    参考: Latex报"Missing $ inserted"的解决方法 Latex: "Missing $ inserted" 解决方法 原因一:在文中出现&q ...

  10. JQGrid 在页面加载时展开SubGrid

    1.jqgrid在加载完成之后展开SubGrid,用得如下办法: gridComplete: function () { var rowIds = $("#list2").getD ...