Submission #41070

#TimeUsernameProblemLanguageResultExecution timeMemory
41070IvanC전압 (JOI14_voltage)C++14
100 / 100
375 ms64020 KiB
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
const int MAXN = 1e5 + 10;
const int MAXM = 2*1e5 + 10;
int e1[MAXM],e2[MAXM],pai[MAXN],ligapai[MAXN],peso[MAXN],N,M,ans;
int possivel,last,oldw[MAXM],oldz[MAXM],oldpai[MAXM],oldliga[MAXM],oldpeso[MAXM],oldpossivel[MAXM];
int find(int x){
	if(x == pai[x]) return x;
	return find(pai[x]);
}
int parity(int x){
	if(x == pai[x]) return 0;
	return (ligapai[x] ^ parity(pai[x]));
}
void join(int x,int y){
	int w = find(x), z = find(y),px = parity(x),py = parity(y);
	if(peso[w] < peso[z]){
		swap(w,z);
		swap(px,py);
		swap(x,y);
	}
	last++;
	oldw[last] = w;
	oldz[last] = z;
	oldpai[last] = pai[z];
	oldliga[last] = ligapai[z];
	oldpeso[last] = peso[w];
	oldpossivel[last] = possivel;
	if(w == z){
		if(px == py) possivel = 0;
		return;
	}
	pai[z] = w;
	peso[w] += peso[z];
	if(px == py) ligapai[z] = 1;
	else ligapai[z] = 0;
}
void undo(){
	int w = oldw[last] , z = oldz[last];
	peso[w] = oldpeso[last];
	pai[z] = oldpai[last];
	ligapai[z] = oldliga[last];
	possivel = oldpossivel[last];
	last--; 
}
void divide_and_conquer(int ini,int fim){
	if(!possivel) return;
	if(ini == fim){
		if(possivel){
			if(find(e1[ini]) != find(e2[ini])) ans++;
			else if(parity(e1[ini]) == parity(e2[ini])) ans++;
		}
		return;
	}
	int meio = (ini+fim)/2;
	for(int i = meio + 1;i<=fim;i++){
		join(e1[i],e2[i]);
	}
	divide_and_conquer(ini,meio);
	for(int i = meio + 1;i<=fim;i++){
		undo();
	}
	for(int i = ini;i<=meio;i++){
		join(e1[i],e2[i]);
	}
	divide_and_conquer(meio+1,fim);
	for(int i = ini;i<=meio;i++){
		undo();
	}
}
int main(){
	scanf("%d %d",&N,&M);
	for(int i = 1;i<=N;i++){
		pai[i] = i;
		peso[i] = 1;
		ligapai[i] = 0;
	}
	possivel = 1;
	for(int i = 1;i<=M;i++){
		scanf("%d %d",&e1[i],&e2[i]);
	}
	divide_and_conquer(1,M);
	printf("%d\n",ans);
	return 0;
}

Compilation message (stderr)

voltage.cpp: In function 'int main()':
voltage.cpp:73:22: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d",&N,&M);
                      ^
voltage.cpp:81:31: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d %d",&e1[i],&e2[i]);
                               ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...