kmjp's blog

競技プログラミング参加記です

yukicoder : No.2678 Minmax Independent Set (Hack)

色々解法がありそう。
https://yukicoder.me/problems/no/2678

問題

No.2677 Minmax Independent Set - yukicoder
をもとにした問題。
先手が次数最大の点上位1000個を選んだ場合でも、後手が高確率で勝利できるようなグラフを構築せよ。

解法

次数最大の点のうち、「そこを先手が取ると先手が負ける」という点を沢山作りこめばよい。
5頂点を1列に並んだパーツを考え、真ん中同士を計19999列分連結しよう。うち、1か所だけは5頂点ではなく3頂点にしておく。
先手は次数4である真ん中同士を連結した点を取りに来るが、うち半分は先手必敗となる。

void solve() {
	int i,j,k,l,r,x,y; string s;
	
	vector<pair<int,int>> E;
	FOR(i,200000/5-1) {
		
		if(i==10000) {
			E.push_back({i*5,i*5+1});
			E.push_back({i*5+1,i*5+2});
			E.push_back({i*5+2-5,i*5+1});
		}
		else if(i==10001) {
			E.push_back({i*5-2,i*5+1-2});
			E.push_back({i*5+1-2,i*5+2-2});
			E.push_back({i*5+2-2,i*5+3-2});
			E.push_back({i*5+3-2,i*5+4-2});
			E.push_back({i*5+1-5,i*5+2-2});
		}
		else if(i<10000) {
			E.push_back({i*5,i*5+1});
			E.push_back({i*5+1,i*5+2});
			E.push_back({i*5+2,i*5+3});
			E.push_back({i*5+3,i*5+4});
			if(i) E.push_back({i*5+2-5,i*5+2});
		}
		else if(i>10001) {
			E.push_back({i*5-2,i*5+1-2});
			E.push_back({i*5+1-2,i*5+2-2});
			E.push_back({i*5+2-2,i*5+3-2});
			E.push_back({i*5+3-2,i*5+4-2});
			E.push_back({i*5+2-5-2,i*5+2-2});
		}
	}
	cout<<E.size()+1<<endl;
	FORR2(a,b,E) cout<<a+1<<" "<<b+1<<endl;
}

まとめ

こっちは★3.5~4でもよさそう。