【loli的胡策】联校11.5(lca)

题意(T1):

给你一个DAG,问1号点到某些点的必经之路的交集大小,保证1号点可到达所有点。
这里写图片描述

题解:

考试时写了树的部分分
你们来自己体会一下题解的语文造诣
这里写图片描述
UPD最终在loser的帮助下总算明白了
有环的话好像没有什么办法了啊。。。。算了我们还是原谅辣鸡出题人吧
先来一张图示
这里写图片描述
这就是题解让我们建的那棵树
这是如何建的呢?一个点连到到达ta的所有点的lca
不难发现,这样一棵树在搜索必经之点的时候,就是要求到的点的lca到达父亲的距离
这也是不难发现的,因为作为一个必经点,ta的lca一定是ta自己
那么如何实现呢?运用类似top的方法,一边遍历一边建树

代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 50005
#define M 100005
#define sz 19
using namespace std;
int tot,nxt[M],point[N],v[M],f[N][sz],h[N],wh[N];
int in[N],hh[N];
queue<int>q;
void addline(int x,int y){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}
void add(int fa,int x)
{
    h[x]=h[fa]+1;
    f[x][0]=fa;
    for (int i=1;i<sz;i++) f[x][i]=f[f[x][i-1]][i-1];
}
int lca(int x,int y)
{
    if (!x) return y;if (!y) return x; 
    if (h[x]<h[y]) swap(x,y);
    int k=h[x]-h[y];
    for (int i=0;i<sz;i++)
      if ((k>>i)&1) x=f[x][i];
    if (x==y) return x;
    for (int i=sz-1;i>=0;i--)
      if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
int main()
{
    freopen("attack.in","r",stdin);
    freopen("attack.out","w",stdout);
    int n,m,Q,i;
    scanf("%d%d%d",&n,&m,&Q);
    for (i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        addline(x,y);in[y]++;
    }
    h[1]=1;
    for (i=1;i<=n;i++) if (!in[i]) q.push(i);
    while (!q.empty())
    {
        int now=q.front(); q.pop(); 
        for (int i=point[now];i;i=nxt[i])
        {
            wh[v[i]]=lca(wh[v[i]],now);
            in[v[i]]--;
            if (!in[v[i]]){q.push(v[i]);add(wh[v[i]],v[i]);}  
        }
    }
    while (Q--)
    {
        int num,fa,xx;
        scanf("%d%d",&num,&fa);
        for (i=2;i<=num;i++){scanf("%d",&xx);fa=lca(xx,fa);}
        printf("%d\n",h[fa]);
    }
}

总结:

反复检查要不要开long long
一些东西要想明白之后再修改,不然只能是画蛇添足

吐槽

联考的日常:
xp:垃圾出题人
dp:裱出题人
圆脸:spj都不会写还来出什么题
yyp:他不是保证第一个字符串比第二个字符串小吗
loser:他的字符串长度都能变成两倍了想什么呢
yq:他(题解)说的是人话吗

考试ing
喵喵喵:今天的出题人这么良心呀!(flag)
期望得分:40+100+100
实际得分:36+30+80
???我感觉还是写的很稳的???
好吧T1的40%你算成36pts我就原谅你了
你T3的原题炸我int我也忍了
你T2数组要两倍是要闹鬼咯?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值