Codeforces 1344 C. Quantifier Question —— 拓扑+基础DP

This way

题意:

给你这么一个关系:
在这里插入图片描述
让你确定Q序列,每个是∀或者∃,使得
在这里插入图片描述
成立
问你最多的∀可以有多少并且将Q序列输出(不懂看样例3)

题解:

很明显,它题目里都说了
在这里插入图片描述
上面是合法的,下面是不合法的,然后根据逻辑推一推就可以知道,如果有这样一个关系a,b。
无论a,b谁在前在后,只有序号比较小的那个能够是∀,剩下一个一定是∃,比如
x1<x2
那么只能x1是∀
x2<x1
依然是x1为∀
推广到更多的情况:一条有向路径上,只有序列最小的那个数才有∀
那么我们dfs做一遍拓扑+DP即可

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int pmi[N],smi[N],ans[N],deg[N],f,sum;
vector<int>son[N];
void dfs(int num,vector<int>vec){
    if(!num){
        for(int i:vec){
            if(pmi[i]>=i)sum++,ans[i]=1;
        }
        return ;
    }
    if(vec.empty()){
        printf("-1\n");
        exit(0);
    }
    vector<int>ne;
    int del=0;
    for(int u:vec){
        for(int i:son[u]){
            deg[i]--;
            pmi[i]=min(pmi[i],pmi[u]);
            if(!deg[i])
                ne.push_back(i),del++;
        }
    }
    dfs(num-del,ne);
    for(int u:vec){
        for(int i:son[u])
            smi[u]=min(smi[u],smi[i]);
        if(pmi[u]>=u&&smi[u]>=u)ans[u]=1,sum++;
    }
}
int main()
{
    int n,m,x,y;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)pmi[i]=smi[i]=i;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y),son[y].push_back(x),deg[x]++;
    vector<int>vec;
    for(int i=1;i<=n;i++)
        if(!deg[i])
            vec.push_back(i);
    dfs(n-vec.size(),vec);
    printf("%d\n",sum);
    for(int i=1;i<=n;i++)
        printf("%c","EA"[ans[i]==1]);
    printf("\n");
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值