P4645 [COCI2006-2007 Contest#3] BICIKLI

Posted olinr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4645 [COCI2006-2007 Contest#3] BICIKLI相关的知识,希望对你有一定的参考价值。

$ \color{#0066ff}{ 题目描述 }$

给定一个有向图,n个点,m条边。请问,1号点到2号点有多少条路径?如果有无限多条,输出inf,如果有限,输出答案模\(10^9\)的余数。

两点之间可能有重边,需要看成是不同的路径。

\(\color{#0066ff}{输入格式}\)

第一行两个整数n,m,表示点数和边数

接下来是m行有向边

\(\color{#0066ff}{输出格式}\)

输出一行表示答案

\(\color{#0066ff}{输入样例}\)

6 7
1 3
1 4
3 2
4 2
5 6
6 5
3 4
    
    
6 8
1 3
1 4
3 2
4 2
5 6
6 5
3 4
4 3

\(\color{#0066ff}{输出样例}\)

3
    
inf

\(\color{#0066ff}{数据范围与提示}\)

1 ≤ N ≤ 10 000, 1 ≤ M ≤ 100 000

\(\color{#0066ff}{题解}\)

路径无限??显然是有环,于是直接tarjan缩点

然后记忆化搜索路径,注意,无解当且仅当路径中有siz>1的分量,为了保证是路径中的,你要在搜到目标的时候再判断!

#include<bits/stdc++.h>
#define LL long long
LL in() {
    char ch; LL x = 0, f = 1;
    while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    return x * f;
}
const int mod = 1e9;
const int maxn = 1e5 + 10;
struct node {
    int to;
    node *nxt;
    node(int to = 0, node *nxt = NULL): to(to), nxt(nxt) {}
};
node *head[maxn];
bool flag;
int dfn[maxn], low[maxn], cnt, st[maxn], top, ins[maxn], num, siz[maxn], bel[maxn], n, m;
LL f[maxn];
bool vis[maxn];
std::vector<int> mp[maxn];
std::set<int> have[maxn];
void add(int from, int to) { head[from] = new node(to, head[from]); }
void tarjan(int x) {
    dfn[x] = low[x] = ++cnt;
    ins[st[++top] = x] = true;
    for(node *i = head[x]; i; i = i->nxt) {
        if(!dfn[i->to]) tarjan(i->to), low[x] = std::min(low[x], low[i->to]);
        else if(ins[i->to]) low[x] = std::min(low[x], dfn[i->to]);
    }
    if(dfn[x] == low[x]) {  
        num++;
        do {
            ins[st[top]] = false;
            bel[st[top]] = num;
            siz[num]++;
            top--;
        }while(st[top + 1] != x);
    }
}
LL dfs(int x, bool now) {
    if(vis[x]) return f[x];
    if(x == bel[2]) {
        if(now) flag = true;
        return f[x] = 1;
    }
    vis[x] = true;
    for(auto go : mp[x]) {
        (f[x] += dfs(go, now | (siz[x] > 1))) %= mod;
        if(flag) return 0;
    }
    return f[x];
}


int main() {
    n = in(); m = in();
    int x, y;
    for(int i = 1; i <= m; i++) x = in(), y = in(), add(x, y);
    for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= n; i++)
        for(node *o = head[i]; o; o = o->nxt)
            if(bel[i] != bel[o->to]) {
                if(have[bel[i]].count(bel[o->to])) continue;
                mp[bel[i]].push_back(bel[o->to]);
            }
    LL ans = dfs(bel[1], 0);
    if(flag) puts("inf");
    else printf("%lld\n", ans);
    return 0;
}

以上是关于P4645 [COCI2006-2007 Contest#3] BICIKLI的主要内容,如果未能解决你的问题,请参考以下文章

[COCI2006-2007#1] Bond

[COCI2006-2007#1] Bond

[COCI2006-2007#1] Slikar

Luogu_4329 [COCI2006-2007#1] Bond

P4329 [COCI2006-2007#1] Bond

题解 P4413 [COCI2006-2007#2] R2