zoukankan      html  css  js  c++  java
  • [UOJ513]【UR #19】清扫银河

    非常有意思的一道题,UR 还是一如既往的高水平……就是我比较菜,赛后 15min 突然一拍大腿想出来怎么做了(

    首先有一个结论:对于任意图,如果存在方案,一定可以在 (m+1) 步内完成。

    证明:首先考虑操作 (2)。先假设所有点都是黑色,逐渐将某些点染白的过程。发现一条边 ((x, y)) 在染白 (x) 时会被翻转,而在染白 (y) 时又会被翻回去。这等价于,将一个点染白时,翻转它所有的连边。因此,每个点最优策略中只会被染白一次,也就是说,(2) 操作只会进行一次,这一次会将所有应该被翻转的点染白。

    再考虑操作 (1)。对每个连通块任意构造一棵生成树,则每个非树边唯一对应了一个简单环。不难发现,图中任意一个简单环都可以由上述简单环异或得到(只需要取出这个简单环中,每条非树边对应的环即可)。换句话说,对于任何一种操作 (1) 中选择简单环的方式,都只需要将最终状态中被翻转的非树边对应的环取出来异或。因此操作 (1) 的数量不会超过非树边数量,且一定 (<m)

    因此,我们只需要判定给定的图是否存在至少一个方案即可。

    假设我们已经选择了 (2^n) 个点集中的一个进行了操作 (2),考虑如何判定是否能通过操作 (1) 变为全 (0)

    首先发现若干简单环构成的图,每个点的度数都是偶数。而这恰好是无向图拥有若干不相交欧拉回路的充要条件。又因为每个欧拉回路都能拆成若干简单环,所以一个图由若干简单环构成,等价于它的每个点度数都是偶数。

    也就是说我们要求操作 (2) 后,每个点都连接了偶数条不能通行的边。再考虑将一个点染白的影响:任何与它直接连边的点,不能通行的边的奇偶性都会改变。如果这个点本身连边数量为奇数,那么它本身的奇偶性也会改变。也就是说,每个点对应了一个长度为 (n)(01) 向量,现在我们需要选出若干向量,使得他们的异或和等于初始状态下,每个点不能通行的边的奇偶性组成的 (01) 向量。这个问题可以用线性基简单解决,复杂度 (O(frac{n^3}{w}))

    Code:

    #include <bits/stdc++.h>
    #define R register
    #define mp make_pair
    #define ll long long
    #define pii pair<int, int>
    using namespace std;
    const int mod = 998244353, N = 320;
    
    int t, n, m;
    bitset<N> bs[N], to[N], dgr;
    
    inline int addMod(int a, int b) {
    	return (a += b) >= mod ? a - mod : a;
    }
    
    inline ll quickpow(ll base, ll pw) {
    	ll ret = 1;
    	while (pw) {
    		if (pw & 1) ret = ret * base % mod;
    		base = base * base % mod, pw >>= 1;
    	}
    	return ret;
    }
    
    template <class T>
    inline void read(T &x) {
    	x = 0;
    	char ch = getchar(), w = 0;
    	while (!isdigit(ch)) w = (ch == '-'), ch = getchar();
    	while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	x = w ? -x : x;
    	return;
    }
    
    int insrt(bitset<N> &x) {
    	for (R int i = n; i; --i) {
    		if (!x[i]) continue;
    		if (bs[i].none()) return bs[i] = x, 1;
    		x ^= bs[i];
    	}
    	return 0;
    }
    
    int main() {
    	int x, y, w;
    	read(t);
    	while (t--) {
    		read(n), read(m);
    		dgr.reset();
    		for (R int i = 1; i <= n; ++i) bs[i].reset(), to[i].reset();
    		for (R int i = 1; i <= m; ++i) {
    			read(x), read(y), read(w);
    			to[x][y] = to[y][x] = 1;
    			to[x][x].flip(), to[y][y].flip();
    			dgr[x] = dgr[x] ^ w, dgr[y] = dgr[y] ^ w;
    		}
    		for (R int i = 1; i <= n; ++i) insrt(to[i]);
    		printf("%s
    ", insrt(dgr) ? "no" : "yes");
    	}
    	return 0;
    }
    
  • 相关阅读:
    C语言volatile
    2017-10-12 下一步计划
    关于步进电机的半流设置、衰减设置
    压力校准仪开发-----步进电机驱动
    kei中实现在线仿真看波形
    42步进电机与57步进电机
    网上的说TB6560存在的问题
    TB6560步进电机驱动板
    继承
    iOS设计模式——单例模式
  • 原文地址:https://www.cnblogs.com/suwakow/p/12635190.html
Copyright © 2011-2022 走看看