zoukankan      html  css  js  c++  java
  • 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
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    python 遍历文件夹 文件
    Docker使用常见问题
    Docker基础技术:DeviceMapper
    更改Docker默认的images存储位置
    NAT方式,宿主机无法ping通虚拟机
    centos7使用问题总结
    VMWare虚拟机提供的桥接、nat和主机模式的区别
    css之'>'
    eclipse安装插件:
    腾讯后台开发面试总结,原创,吐血推荐!!
  • 原文地址:https://www.cnblogs.com/olinr/p/10628047.html
Copyright © 2011-2022 走看看