• 「题解」Codeforces 402E Strictly Positive Matrix


    orz 峰

    由于不是正数就是 (0),可以把正数看成 (1),变成了 (01) 矩阵。

    邻接矩阵的 (k) 次幂中,({A^k}_{i,j}) 代表 (i)(j) 是否有长度为 (k) 的路径。

    这个题变成了是否存在一个 (k),使得任意两点之间都有长度为 (k) 的路径,初始给的 (A) 即为告诉你哪些点直接直接有边相连。

    数据保证了 (sum_{i=1}^n a_{i,i}>0),也就是至少存在一个子环。

    那么问题可以转化为给你一张点数为 (n) 的有向图,询问是否两两强连通。因为一定存在一个自环,则可以把 (k) 看作一个很大的数,如果让一个点走到另一个点的时候先走到那个自环的位置把多余的路程消耗完了,再走到目的地的点,即可看为任意两点都有长度为 (k) 的路径。

    点数 (leq 2000),边数 (leq 2000^2),直接 dfs 是 (mathcal{O}(n^3)) 的。考虑实际上是问整张图是否是一个 SCC,直接 Tarjan 缩点即可。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<cstring>
    typedef long long ll;
    ll mod;
    template <typename T> T Add(T x, T y) { return (x + y >= mod) ? (x + y - mod) : (x + y); }
    template <typename T> T cAdd(T x, T y) { return x = (x + y >= mod) ? (x + y - mod) : (x + y); }
    template <typename T> T Mul(T x, T y) { return x * y % mod; }
    template <typename T> T Mod(T x) { return x < 0 ? (x + mod) : x; }
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T> T Abs(T x) { return x < 0 ? -x : x; }
    template <typename T> T chkmax(T &x, T y) { return x = x > y ? x : y; }
    template <typename T>
    T &read(T &r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = (r << 3) + (r <<1) + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    inline int lowbit(int x) { return x & (-x); }
    int popcount(int x) { int sumq = 0;	while(x) x -= lowbit(x), ++sumq; return sumq; }
    ll qpow(ll x, ll y) {
    	ll sumq = 1;
    	while(y) {
    		if(y & 1) sumq = sumq * x % mod;
    		x = x * x % mod;
    		y >>= 1;
    	}
    	return sumq;
    }
    const int N = 2010;
    std::queue<int>q;
    std::stack<int>st;
    int n, m, a[N][N];
    int dfn[N], low[N], icnt;
    int va[N], val[N], blo[N], bnt, f[N];
    bool vis[N];
    //Edge----------------------------
    int head[N], ent;
    struct Edge {
    	int next, to;
    }e[N*N];
    inline void add(int x, int y) {
    	e[++ent].to = y; e[ent].next = head[x]; head[x] = ent;
    }
    //dfs-----------------------------
    void dfs(int x) {
    	dfn[x] = low[x] = ++icnt; st.push(x);
    	for(int i = head[x]; i; i = e[i].next) {
    		int v = e[i].to;
    		if(blo[v]) continue;
    		if(!dfn[v]) {
    			dfs(v);
    			low[x] = Min(low[x], low[v]);
    		}
    		else low[x] = Min(low[x], dfn[v]);
    	}
    	if(low[x] == dfn[x]) {
    		++bnt;
    		do {
    			int top = st.top(); st.pop();
    			val[bnt] += va[top];
    			blo[top] = bnt;
    			if(top == x) break;
    		} while(true);
    	}
    }
    void dfs2(int x) {
    	if(vis[x]) return ;
    	vis[x] = 1;
    	for(int i = head[x]; i; i = e[i].next)
    		dfs2(e[i].to);
    }
    signed main() { //freopen("in.txt", "r", stdin);
    	read(n);
    	for(int i = 1; i <= n; ++i)
    		for(int j = 1; j <= n; ++j) {
    			read(a[i][j]);
    			if(a[i][j] && i != j) add(i, j);
    		}
    	for(int i = 1; i <= n; ++i)
    		if(!dfn[i])
    			dfs(i);
    	if(bnt == 1) puts("YES");
    	else puts("NO");
    	return 0;
    }
    
  • 相关阅读:
    hadoop 主机名 无法访问问题解决汇总
    Linux 集群时间同步(Ubuntu)
    odoo里面的一些ORM操作
    odoo12动作里添加向导
    odoo看板笔记
    odoo中接口开发
    odoo视图 “动作” 里添加菜单按钮:案例
    odoo源码学习之任务中的阶段字段stage_id
    python中的abstractmethod
    U盘启动盘安装win10出现cdboot:couldn't find ntldr
  • 原文地址:https://www.cnblogs.com/do-while-true/p/15047852.html
Copyright © 2020-2023  润新知