很久很久以前的一天,一位美男子來(lái)到海邊,海上狂風(fēng)大作。美男子希望在海中找到美人魚(yú),但是很不幸他只找到了章魚(yú)怪。
然而,在世界的另一端,人們正在積極的收集怪物的行為信息,以便研制出強(qiáng)大的武器來(lái)對(duì)付章魚(yú)怪。由于地震的多發(fā),以及惡劣的天氣,使得我們的衛(wèi)星不能很好的定位怪物,從而不能很好的命中目標(biāo)。第一次射擊的分析結(jié)果會(huì)反映在一張由n個(gè)點(diǎn)和m條邊組成的無(wú)向圖上。現(xiàn)在讓我們來(lái)確定這張圖是不是可以被認(rèn)為是章魚(yú)怪。
為了簡(jiǎn)單起見(jiàn),我們假設(shè)章魚(yú)怪的形狀是這樣,他有一個(gè)球形的身體,然后有很多觸須連接在他的身上。可以表現(xiàn)為一張無(wú)向圖,在圖中可以被認(rèn)為由三棵或者更多的樹(shù)(代表觸須)組成,這些樹(shù)的根在圖中處在一個(gè)環(huán)中(這個(gè)環(huán)代表球形身體)。
題目保證,在圖中沒(méi)有重復(fù)的邊,也沒(méi)有自環(huán)。
Input單組測(cè)試數(shù)據(jù)第一行給出兩個(gè)數(shù),n表示圖中的點(diǎn)的個(gè)數(shù),m表示圖中邊的數(shù)量。 (1≤ n≤100,0≤ m≤ n*(n-1)/2 )接下來(lái)m行給出邊的信息,每一行有兩上數(shù)x,y (1≤ x,y≤ n,x≠y)表示點(diǎn)x和點(diǎn)y之間有邊相連。每一對(duì)點(diǎn)最多有一條邊相連,點(diǎn)自身不會(huì)有邊到自己。Output共一行,如果給定的圖被認(rèn)為是章魚(yú)怪則輸出"FHTAGN!"(沒(méi)有引號(hào)),否則輸出"NO"(沒(méi)有引號(hào))。Input示例6 66 36 45 12 51 45 4Output示例FHTAGN!思路:
按照題目要求一步一步來(lái),首先這圖中一定有且只有一個(gè)長(zhǎng)度不小于3的環(huán),所以需要dfs搜索找到環(huán),并且將環(huán)中的節(jié)點(diǎn)保存下來(lái)。這里我是利用一個(gè)deep數(shù)組來(lái)儲(chǔ)存每個(gè)節(jié)點(diǎn)在dfs樹(shù)中的深度,一開(kāi)始deep都初始化成0,第一個(gè)遍歷的根節(jié)點(diǎn)deep是1,然后子節(jié)點(diǎn)依次+1,當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn)都遞歸結(jié)束的時(shí)候,當(dāng)前節(jié)點(diǎn)的deep值變回0,當(dāng)?shù)竭_(dá)一個(gè)新的節(jié)點(diǎn)并且新的節(jié)點(diǎn)deep值不為0的時(shí)候,說(shuō)明這里存在一個(gè)環(huán),而組成環(huán)的節(jié)點(diǎn)就是deep值在當(dāng)前節(jié)點(diǎn)u已經(jīng)由的deep[u]和又一次對(duì)其賦值的k+1之間。當(dāng)找到一個(gè)環(huán)的時(shí)候,剩下的就是要判斷以環(huán)上的每個(gè)點(diǎn)遍歷下去是否是一棵樹(shù),這里要注意,要先將環(huán)上的邊都刪掉,然后將環(huán)上的所有節(jié)點(diǎn)的訪問(wèn)標(biāo)記vis都設(shè)成true。這樣,當(dāng)dfs過(guò)程中遇到了vis為true的情況,則說(shuō)明存在另外的環(huán),輸出“NO"。vis的另外的作用就是判斷圖是否連通。如果有節(jié)點(diǎn)的vis在判斷完環(huán)上所有節(jié)點(diǎn)之后還是false,那說(shuō)明圖不連通。代碼:
#include <bits/stdc++.h>using namespace std;const int MAXN = 105;int n, m;bool G[MAXN][MAXN], vis[MAXN];int deep[MAXN];vector <int> cir;int l, r;bool cmp(const int x, const int y) { return deep[x] < deep[y];}bool dfs(int u, int PRe, int k) { deep[u] = k; vis[u] = true; for (int v = 1; v <= n; v++) { if (!G[u][v] || v == pre) continue; if (vis[v]) { l = deep[v]; r = k + 1; return true; } if (dfs(v, u, k + 1)) return true; } deep[u] = 0; return false;}int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); G[u][v] = G[v][u] = true; } if (!dfs(1, -1, 1)) { puts("NO"); return 0; } for (int i = 1; i <= n; i++) { if (deep[i] >= l && deep[i] <= r) { cir.push_back(i); // printf("%d ", i); } } if (cir.size() < 3) { puts("NO"); return 0; } sort(cir.begin(), cir.end(), cmp); int cnt = cir.size(); for (int i = 0; i < cnt - 1; i++) G[cir[i]][cir[i + 1]] = G[cir[i + 1]][cir[i]] = false; G[cir[0]][cir[cnt - 1]] = G[cir[cnt - 1]][cir[0]] = false; memset(deep, 0, sizeof(deep)); memset(vis, false, sizeof(vis)); for (int i = 0; i < cnt; i++) vis[cir[i]] = true; for (int i = 0; i < cnt; i++) { if (dfs(cir[i], -1, 1)) { puts("NO"); return 0; } } for (int i = 1; i <= n; i++) { if (!vis[i]) { puts("NO"); return 0; } } puts("FHTAGN!"); return 0;}
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注