CF1610F F. Mashtali: a Space Oddysey

We first found the following properties:
We might as well orient the edges randomly first, so we find that no matter how we flip the edges.
Will cause \ (2 / 4 \) impact on the points at both ends, so we find that if the sum of all edge weights connected to a point is even, we can't adjust it as a good point.

Then we naturally think about whether we can construct a scheme so that all edge weights and odd numbers can become good points.

We first give a scheme and then prove it.

For all singularity points, we are connected to an imaginary point, a virtual edge with edge weight \ (1 \).

We know that an edge will change the degree parity of two points at the same time, that is, the odd degree points are even.

So after we operate, all points must be even, and this graph is an Euler loop.

When we traverse the Euler loop, we first satisfy that the edge weights of the outgoing edge and the incoming edge are equal, otherwise we use the other side.

Considering that we can orient arbitrarily when the edge weight is even, we don't consider it.

Then we consider the case where the edge weight is odd, then there are two cases.

1: Odd numbered edges with edge weight of \ (1 \), odd numbered edges with edge weight of \ (2 \).

In this case, according to our operation, we will only offset to one edge with edge weight of \ (1 \) and one edge with edge weight of \ (2 \).

Then it's better.

1: Odd number of edges with edge weight of \ (1 \) and even number of edges with edge weight of \ (2 \).

In this case, according to our operation, we will only offset until only one edge weight is \ (1 \).

Then it's better.

So as long as we follow this operation, we can make all odd points of edge weight sum be good points.

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<list>
#define ll lonng long
#define N 600005

bool begin;

int n,m;

int to[N];
int from[N];

int sum[N];

int fans,ans[N];

int vis[N];

int cnt[N];

std::vector<int>Q[N][3];//The edge weight is 1 and the edge weight is 2
int head[N][3];

int dfn[N];

bool end;

inline void dfs(int u,int now){
//	std::cout<<u<<" "<<now<<std::endl;
//	std::cout<<"rest"<<head[u][now]<<" "<<head[u][3 - now]<<std::endl;
	int fnow = now;
	while(!(Q[u][now].size() <= head[u][now] && Q[u][3 - now].size() <= head[u][3 - now])){
	dfn[u] = 1;
	while(head[u][now] < Q[u][now].size() && vis[Q[u][now][head[u][now]]])
	head[u][now] ++;	
	while(head[u][3 - now] < Q[u][3 - now].size() && vis[Q[u][3 - now][head[u][3 - now]]])
	head[u][3 - now] ++;	
	if(Q[u][now].size() != head[u][now]){
		ans[Q[u][now][head[u][now]]] = (u == from[Q[u][now][head[u][now]]]) + 1;
		vis[Q[u][now][head[u][now]]] = 1;
//		std::cout<<"("<<u<<"->"<<" "<<(to[Q[u][now][head[u][now]]] - u)<<")"<<std::endl;
//		std::cout<<Q[u][now].front()<<std::endl;
		dfs(to[Q[u][now][head[u][now]]] - u,now);
		head[u][now] ++ ;
	}else{
		now = 3 - now;
		if(Q[u][now].size() != head[u][now]){
		ans[Q[u][now][head[u][now]]] = (u == from[Q[u][now][head[u][now]]]) + 1;
		vis[Q[u][now][head[u][now]]] = 1;
//		std::cout<<"("<<u<<"->"<<" "<<(to[Q[u][now][head[u][now]]] - u)<<")"<<std::endl;		
//		std::cout<<Q[u][now].front()<<std::endl;
		dfs(to[Q[u][now][head[u][now]]] - u,now);
		head[u][now] ++ ;
	}	
	}
	now = fnow;
	}
	return ;
}

int main(){
//	std::cout<<(&end - &begin) / 1024 / 1024<<std::endl;
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= m;++i){
		int x,y,p;
		scanf("%d%d%d",&x,&y,&p);
		to[i] = x + y;
		cnt[x] ++ ;
		cnt[y] ++ ;
		from[i] = x;
		sum[x] += p;
		sum[y] += p;
		Q[x][p].push_back(i);
		Q[y][p].push_back(i);
	}
	int mcnt = m;
	for(int i = 1;i <= n;++i){
		if(sum[i] & 1)
		fans ++ ;
		if(cnt[i] & 1){
			int x = n + 1;
			int y = i;
			int p = 1;
			to[++mcnt] = x + y;
			from[mcnt] = x;
			Q[x][p].push_back(mcnt);
			Q[y][p].push_back(mcnt);
		}
	}
	for(int i = 1;i <= n + 1;++i)
	if(!dfn[i])
	dfs(i,1);
	std::cout<<fans<<std::endl;
	for(int i = 1;i <= m;++i)
	std::cout<<(ans[i]);
	return 0;
}

Keywords: Graph Theory

Added by ArneR on Fri, 26 Nov 2021 11:47:18 +0200