1. 程式人生 > 其它 >Atcoder Beginner Contest 209 E Shiritori

Atcoder Beginner Contest 209 E Shiritori

Atcoder Beginner Contest 209 E Shiritori

題目連結:https://atcoder.jp/contests/abc209/tasks/abc209_e

​ 很容易想到這是一幅圖。我們將每個單詞的前三個字母向後三個字母連一條邊。然後就構成了一幅有向的圖。對於這幅圖來說,如果一個人走到了一個沒有出度的點,那麼他就贏了,因為另一個人不能再說出任何一個單詞(走到另外一個點)。我們用一個 \(dp\) 陣列表示從這個點開始遊戲的輸贏情況,0 表示平局,1 表示 Takahashi 贏,2 表示 Aoki 贏。那麼顯然,所有出度為 0 的點的 \(dp\) 值都為1。

​ 現在我們考慮 \(dp\)

陣列的轉移。如果一個點所有能走到的點當中,有一個點的 \(dp\) 值為 1。那麼這個點的 \(dp\)肯定為 2。因為 Aoki 只要往這個點上走,那麼他就贏了。如果這個點能到達的所有點的 \(dp\) 值為 2,那麼這個點的 \(dp\) 值才能為 1。如果一個點不符合上述的兩種情況,那麼它的 \(dp\) 值就是 0 了,因為能更新狀態為 1,2,的只有上述兩種情況,然後這個點一定是 0,1,2 中的一個,只有可能是 0了。

​ 然後我們反向連邊,將所有入度為 0 的點的 \(dp\) 值設定為 1。然後跑一趟拓撲排序就好了。當然,這裡的拓撲排序要魔改一下,如果一個點的 \(dp\) 值被確定為 1 或 2 了,可以立馬扔進佇列中,因為根據我們上面的轉移,它不可能再被更改了。這樣操作可以讓拓撲排序滲透到一些環中。對於一些環來說,環的某一部分是可以被更新到的,一部分又是無法被更新到的,而可以被更新到的點中它們被更新的狀態是不同的,簡而言之,一個環中所有點的 \(dp\)

值是不同的,所以我們不能縮點進行拓撲,而是直接進行拓撲,對於更新不到的點,那麼就是平局了。建議手搓幾組樣例更好的理解(文筆不好,講不清楚

程式碼如下:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+5;
int n,dp[MAXN],in[MAXN],tot,p[MAXN];
char s[10];
map <string,int> mp;
vector <int> edge[MAXN];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	{
		scanf("%s",s+1);
		int len=strlen(s+1);
		string u="",v="";
		for(int j=1;j<=3;++j) u+=s[j];
		for(int j=len-2;j<=len;++j) v+=s[j];
		if(!mp.count(u)) mp[u]=++tot;
		if(!mp.count(v)) mp[v]=++tot;
		p[i]=mp[v];in[mp[u]]++;
		edge[mp[v]].push_back(mp[u]);
	}
	queue <int> q;	
	for(int i=1;i<=tot;++i)
	{
		if(!in[i])
		{
			dp[i]=1;
			q.push(i);
		}
	}
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		for(int i=0;i<edge[now].size();++i)
		{
			int to=edge[now][i];
			if(dp[to]==0)
			{
				in[to]--;
				if(dp[now]==1) dp[to]=2,q.push(to);
				else if(in[to]==0)
				{
					dp[to]=1;
					q.push(to);
				}
			}
		}
	}
	for(int i=1;i<=n;++i)
	{
		if(dp[p[i]]==1) printf("Takahashi\n");
		else if(dp[p[i]]==2) printf("Aoki\n");
		else printf("Draw\n");
	}
}

​ 像這種題目,平局的轉移不好判定,那麼我們將另外兩種判定出來,其他情況就是平局了。換句話說,如果一個集合的子集不好求,我們可以求這個子集的補集,從而得到這個子集。這在某些題目中也是一種優秀的方法。

路漫漫其修遠兮,吾將上下而求索。