제출 #1363408

#제출 시각아이디문제언어결과실행 시간메모리
1363408stanirinaLove Polygon (BOI18_polygon)C++20
100 / 100
892 ms86280 KiB
#include <bits/stdc++.h>

using namespace std;

int n;
map<string, string> g;
map<string, vector<string>> og;
map<string, bool> ucik;
map<string, int> kc;
map<string,int> nkc;

void dfs(string c, string p){
	bool ok=false;
	nkc[c]=0;
	for(auto a:og[c]){
		if(a==p)continue;
		if(ucik[a])continue;
		dfs(a,c);
		nkc[c]+=kc[a];
		if(nkc[a]==kc[a])ok=true;
	}
	kc[c]=nkc[c];
	if(ok)kc[c]++;
}

int main(){
	
	//pravljenje grafa, obrnutog grafa, ulaz
	
	cin>>n;
	for(int i=0;i<n;i++){
		string s,t;
		cin>>s>>t;
		g[s]=t;
		og[t].push_back(s);
	}
	if(n%2==1){
		cout<<-1<<endl;
		return 0;
	}
	
	// deljenje cvorova na one koji pripadaju nekom ciklusu i one koji ne na normalnom grafu
	map<string, bool> vis2;
	map<string,int> vis;
	for(auto a:g){
		vis[a.first]=-1;
		vis2[a.first]=false;
		ucik[a.first]=false;
		kc[a.first]=0;
		nkc[a.first]=0;
	}
	int col=0;
	for(auto a:vis){
		col++;
		if(a.second!=-1)continue;
		string t=a.first;
		while(vis[t]==-1){
			vis[t]=col;
			t=g[t];
		}
		
		if(vis[t]!=col)continue;
		while(!ucik[t]){
			ucik[t]=true;
			t=g[t];
		}
	}
	///for(auto a:ucik)cout<<a.first<<' '<<a.second<<endl;
	
	// postavljanje i pokretanje dpa iz svakog cvora koji pripada ciklusu, na obrnutom grafu
	for(auto a:ucik){
		if(!a.second)continue;
		dfs(a.first, ".");
	}
	
	/// dva dpa, jedan je kada koristimo cvor, drugi kada ne
	/// na pocetku su oba 0
	/// kada ne koristimo, to je zbir sve dece kada ih koristimo
	/// kada korsitimo, vidimo da li je za neko dete isto kada korsitimo i kada ne, ako jeste onda je to kao kad ne koristimo pa plus jedan, u suprotnom je isto
	
	// prolazimo kroz sve cikluse, sabiramo dpove kada koristimo cvor, pratimo duzinu nizove gde je razlika nula, kada se niz prekine na zbir dodajemo niz podeljeno sa dva celobrojno
	
	int sum=0;
	for(auto a:ucik){
		if(!a.second)continue;
		if(vis2[a.first])continue;
		string t=a.first;
		if(t!=g[t] && g[g[t]]==t){
			sum+=nkc[t]+nkc[g[t]]+2;
			vis2[t]=true;
			vis2[g[t]]=true;
			continue;
		}
		int niz=0;
		string p=t;
		t=g[t];
		while(t!=p && kc[t]==nkc[t])t=g[t];
		//cout<<t<<endl;
		while(true){
			//cout<<t<<' ';
			if(vis2[t]){
				sum+=niz/2;
				break;
			}
			
			vis2[t]=true;
			sum+=kc[t];
			if(kc[t]==nkc[t])niz++;
			else{
				sum+=niz/2;
				//cout<<niz/2<<endl;
				niz=0;
			}
			t=g[t];
		}
		//cout<<endl;
	}
	
	// ispisujemo
	//for(auto a:ucik){cout<<a.first<<' '<<kc[a.first]<<' '<<nkc[a.first]<<endl;}
	cout<<n-sum<<endl;
	
	return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…