P4645 [COCI2006-2007#3] BICIKLI(Tarjan+topsort求到某点的方案数)

P4645 COCI2006-2007#3 BICIKLI - 洛谷 | 计算机科学教育新生态

思路:

我们考虑输出inf的情况,可以发现当从1出发到2经过的任意一个点处于一个环内时,路径条数是无穷多的。

有向图上从s到t的经过点,就是从s出发所能经过的所有点与从t出发在反图上所能经过的所有点的交集。

进行拓扑排序时的点的入度,是从s出发所能经过的所有点与从t出发在反图上所能经过的所有点的交集的这张图上的入读,那些不能既被s经过又被t经过的点到这张图上的边所提供的入度是无用的。

Code:

cpp 复制代码
constexpr int N=1e5+5,mod=1e9;

#define fi first
#define se second

int n,m;
int low[N],dfn[N],stk[N],instk[N],tot,top;
int scc[N],sz[N],cnt;
vector<int> e[N],e1[N];
PII p[N];
bool vis1[N],vis2[N];
int d[N],ans[N];

void Tarjan(int u)
{
    dfn[u]=low[u]=++tot;
    stk[++top]=u,instk[u]=1;
    for(auto t:e[u])
    {
        if(!dfn[t])
        {
            Tarjan(t);
            low[u]=min(low[u],low[t]);
        }
        else if(instk[t]) low[u]=min(low[u],dfn[t]);
    }

    if(dfn[u]==low[u])
    {
        int y;
        ++cnt;
        do{
            y=stk[top--];instk[y]=0;
            scc[y]=cnt;
            sz[cnt]++;
        }while(y!=u);
    }
}

void dfs1(int u)
{
    if(vis1[u]) return ;
    vis1[u]=true;
    for(auto t:e[u])
    {
        dfs1(t);
        d[t]++;
    }
}

void dfs2(int u)
{
    if(vis2[u]) return ;
    vis2[u]=true;
    for(auto t:e1[u])
    {
        dfs2(t);
    }
}

void solve()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>p[i].fi>>p[i].se;
        e[p[i].fi].push_back(p[i].se);
        e1[p[i].se].push_back(p[i].fi);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i]) Tarjan(i);
    dfs1(1),dfs2(2);

    for(int i=1;i<=n;i++)
    {
        if(vis1[i]&&vis2[i]&&sz[scc[i]]!=1)
        {
            cout<<"inf";
            return ;
        }
    }

    queue<int> q;
    q.push(1);
    ans[1]=1;
    while(q.size())
    {
        int t=q.front();q.pop();
        for(int v:e[t])
        {
            if(vis2[v])
            {
                ans[v]=(ans[v]+ans[t])%mod;
                d[v]--;
                if(!d[v]) q.push(v);
            }
        }
    }
    cout<<ans[2];
}
相关推荐
m0_639906942 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
Sakura_j_h_3 小时前
EasyEDA PCB 快速设计Skills
c++·python·github
ZhengEnCi3 小时前
Agent 架构怎么选:从单 Agent 到多 Agent 编排的选型决策指南
算法·架构
程序喵大人4 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
秋天的怀念_David4 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Pniubi4 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
hhb_6184 小时前
大模型落地三重优化实战
人工智能·算法·机器学习
云和数据.ChenGuang5 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
jimy16 小时前
C++ 中的 `T&&`:右值引用与转发引用
开发语言·c++
2601_970703836 小时前
工业除湿机租赁:把一份租金合同拆开看
大数据·数据结构·算法·数据库架构·推荐算法