题意:给N(size: 1e5)个单词(size: [0,1000])两个单词能连在一起的条件是前单词的最后一个字母和后单词的第一个字母相同,问能否将这N个单词连在一起。
思路:欧拉通路的判断,同一个单词首末字母建边,然后判断路是否走过了所有单词,可以用DFS或并查集判断。
DFS:
# include <bits/stdc++.h> # define pb push_back using namespace std; char s[1003]; int in[28], out[28], cnt[28], icount; int num; vector<int>v[28]; void dfs(int x, int p) { while(cnt[x] < v[x].size()) dfs(v[x][cnt[x]++],p+1); ++icount; } int main() { int t, n, st; scanf("%d",&t); while(t--) { num = icount = 0; memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); memset(cnt, 0, sizeof(cnt)); for(int i=0; i<26; ++i) v[i].clear(); scanf("%d",&n); int a, b; num = n+1;//N条边相连有N+1个节点。 while(n--) { scanf("%s",s); int len = strlen(s); a = s[0]-'a', b = s[len-1]-'a'; ++in[b]; ++out[a]; v[a].pb(b); } st = a; int s=0, r=0, q=0; for(int i=0; i<26; ++i) { int sub = in[i] - out[i]; if(sub == -1) {++s; st=i;} else if(sub == 1) ++r; else if(sub != 0) ++q; } if(q || r>1 || s>1 || r+s == 1) {puts("The door cannot be opened.");continue;} dfs(st, 1); if(icount == num) puts("Ordering is possible.");//是否遍历了N+1个节点。 else puts("The door cannot be opened."); } return 0; }