zoukankan      html  css  js  c++  java
  • 「题解」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;
    }
    
  • 相关阅读:
    接口测试工具postman学习
    接口测试工具jmeter压力测试
    WSGI规范
    ADB命令详解
    eclipse导入远端git
    os.system、os.popen和subprocess.popen的区别
    获取Android当前运行最顶层的activity
    python+appuim 处理系统权限弹窗
    Appium之xpath定位元素
    Charles配置抓取HTTPS请求的Android配置
  • 原文地址:https://www.cnblogs.com/do-while-true/p/15047852.html
Copyright © 2011-2022 走看看