首页 > 其他分享 >CodeForces 1610F Mashtali: a Space Oddysey

CodeForces 1610F Mashtali: a Space Oddysey

时间:2023-08-11 22:34:23浏览次数:48  
标签:typedef Mashtali Space int 边权 CodeForces long maxn bmod

洛谷传送门

CF 传送门

比较有启发性的题。

首先,设 \(a_u\) 为与点 \(u\) 相连的边权和,答案的上界显然是 \(\sum\limits_{i = 1}^n [a_u \bmod 2 = 1]\)。

之后我们把 P7816 「Stoi2029」以父之名第一篇题解的做法搬过来,也就是:

  1. 建一个虚点向原图度数为奇数的点连边权为 \(1\) 的边,以保证新图中每个点的度数都为偶数,
  2. 在新图上直接跑欧拉回路,顺便根据访问的方向给每条边定向。注意进入一个点时优先选择与入边边权相同的边出去,再选择不同的。

可以证明这样的构造方法能达到答案上界。对于 \(a_u \bmod 2 = 1\) 的点:

  • 若 \(deg_u \bmod 2 = 1\),也就是它向虚点连边,那么连完边后与 \(u\) 相连的边权为 \(1\) 和 \(2\) 的边的数量都为偶数,也就是我们总是能选择一条与入边边权相同的出边。这样减去向虚点连的边,符合条件。
  • 若 \(deg_u \bmod 2 = 0\),也就是它不向虚点连边,那么在原图中与 \(u\) 相连的边权为 \(1\) 和 \(2\) 的边的数量都为奇数。这样我们会恰好有一次入边边权与出边边权不等的情形,也满足条件。

对于 \(a_u \bmod 2 = 0\) 的点,因为它本来就不可能满足条件,所以不用管它。

于是我们就证明了这个构造方法是正确的。

注意图可能不连通。

code
// Problem: F. Mashtali: a Space Oddysey
// Contest: Codeforces - Codeforces Global Round 17
// URL: https://codeforces.com/problemset/problem/1610/F
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;

const int maxn = 1000100;

int n, m, deg[maxn], a[maxn], ans[maxn], b[maxn];
bool vis[maxn];
vector<pii> G[maxn][3];

void dfs(int u, int k) {
	vis[u] = 1;
	for (int t = k, o = 0; o < 2; ++o, t ^= 3) {
		while (G[u][t].size()) {
			pii p = G[u][t].back();
			G[u][t].pop_back();
			int v = p.fst, d = p.scd;
			if (ans[d]) {
				continue;
			}
			ans[d] = (u == b[d] ? 1 : 2);
			dfs(v, t);
		}
	}
}

void solve() {
	scanf("%d%d", &n, &m);
	for (int i = 1, u, v, d; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &d);
		++deg[u];
		++deg[v];
		a[u] += d;
		a[v] += d;
		G[u][d].pb(v, i);
		G[v][d].pb(u, i);
		b[i] = u;
	}
	for (int i = 1; i <= n; ++i) {
		if (deg[i] & 1) {
			G[i][1].pb(n + 1, m + i);
			G[n + 1][1].pb(i, m + i);
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (!vis[i]) {
			dfs(i, 1);
		}
	}
	int cnt = 0;
	for (int i = 1; i <= n; ++i) {
		cnt += (a[i] & 1);
	}
	printf("%d\n", cnt);
	for (int i = 1; i <= m; ++i) {
		printf("%d", ans[i]);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,Mashtali,Space,int,边权,CodeForces,long,maxn,bmod
From: https://www.cnblogs.com/zltzlt-blog/p/17624064.html

相关文章

  • 【题解】Educational Codeforces Round 147(CF1821)
    自己做出来了A-E,F算是搞懂GF后第一道符合我这个菜鸡水平的实战,可惜的是根本没意识到可以GF。A.Matching题目描述:整数模板是每位均为数字或问号的字符串。如果可以用数字替换模板中的每个问号,从而获得该正整数(严格大于\(0\))的十进制表示形式,且不带任何前导零,则该正整数......
  • Codeforces Round 874 (Div. 3) 题解
    A.MusicalPuzzle字符串\(s\)的不同的长度为\(2\)的子串个数就是答案可以用set处理B.RestoretheWeather将\(a\)数组排序后,在\(b\)数组中找到第一个大于等于\(a_i-k\)的元素与\(a_i\)对应即可可以用multiset实现(用multiset自带的lower_bound()比较好,......
  • Codeforces Round 878 (Div. 3) 题解
    A.CipherShifer从头开始扫一遍即可,扫到两个相同的表示某一个字符的解密结束B.BinaryCafe首先,我们不妨把题意转换为有多少种不同的花钱方案因为每一种咖啡就是一个二进制有\(k\)位的数字的其中一位,而对于不同的方案,其二进制位不完全相同,则每一个方案对应的花费一定不同,......
  • java heap space解决方法
    在JVM中如果98%的时间是用于GC(Garbage Collection)且可用的Heapsize不足2%的时候将抛出异常信息,java.lang.OutOfMemoryError:Javaheapspace。所以产生这个异样的原因通常有两种:1.程序中出现了死循环2.程序占用内存太多,超过了JVM堆设置的最大值。对于第一种情况,需要自己查看......
  • 【题解】Educational Codeforces Round 148(CF1832)
    A.NewPalindrome题目描述:给你一个由小写字母组成的回文字符串,问你是否能在重排其之后构造出另一个与原串不同的回文字符串。多测,\(t\le1000,2\le|s|\le50\)题目分析:考虑其实就是前\(\lfloor\frac{n}{2}\rfloor\)个位置存在两种或以上的不同字符,因为这样直接交换对......
  • Codeforces 1857E:Power of Points 区间?
    1857E.PowerofPointsDescription:\(n\)个数:\(x_1,···,x_n\),从左向右扫,当\(s=x_i\)时,可以将这\(n\)个数分为若干个闭区间\([s,x_1],[s,x_2],···,[s,x_n]\)(当然如果\(x_i<s\),则区间形如\([x_i,s]\))对于每一个\(s\in(x_1,···,x_n),\)有一个整数\(p\),记\(f_......
  • Codeforces Round 881 (Div. 3)
    A.SashaandArrayColoring为了让贡献最大,每种颜色只能染两个数显然这两个数为最大值与最小值、次大值与次小值、第三大值与第三小值……以此类推即可B.LongLong为了让和最大,我们需要的就是把所有负数变成正数那么第一问的答案就是\(\sum_{i=1}^n|a_i|\)此外,因为每次变......
  • Codeforces Round 891 (Div. 3) A-G
    偷偷摆烂导致小号掉了16分,但是队友涨了16分,一定是米哈游的问题!A.ArrayColoring题意:给出一个长为\(n\)的数组,问能否把所有元素分别染成两种颜色中的一种,并且使得同种颜色的元素和它们最后的奇偶性相同。Solution算出奇数个数看是不是奇数个即可voidsolve(){ intn;cin>>n......
  • Codeforces Round 891 (Div. 3)
    A.ArrayColoring#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;cin>>n;intsum=0;for(inti=1,x;i<=n;i++)cin>>x,sum+=x;if(sum%2==0)cout<<&quo......
  • Codeforces Round 891 (Div. 3) 题解
    A.ArrayColoring因为:偶数+偶数=偶数奇数+奇数=偶数奇数+偶数=奇数所以设\(s1\)为奇数之和,\(s2\)为偶数之和\(s2\)必定是偶数如果奇数的个数为偶数,则\(s1\)为偶数;否则是奇数而在\(s1\)为奇数时,即使拿一个奇数加到\(s2\)里,那么也是不合法的所以直接判断奇数的......