首先我們可以明確一點,這就是一個圖的遍歷,找一個點,設為起點,建立一個搜索遍歷樹,對于樹每一個點,我們完全可以控制奇偶性,假設:
目前訪問的點為v,父節點為fa,如若點v不符合當前的奇偶性,則就讓父節點到v繞一次,這樣 odd[v] ^= 1, fa[v] ^= 1,這樣我們可以完全保證完全控制子節點,將不符合要求的奇偶性調整成符合要求的奇偶性。同時父節點的奇偶性也在改變。
通過上述的操作,我們可以每次保證子節點的奇偶性符合要求,然而父節點的奇偶性如若不符合要求,則可以通過調整父節點 與 父節點的父節點來調整奇偶性,這樣我們就可以奇偶性傳遞,最終傳遞到根節點。根節點如若不符合該如何調整呢?由于我們是走遍歷樹,到達葉節點還要回來的,意味著我們要走至少兩次根節點,一次是出發,一次是最后一次回歸。我們可以將根節點 r1 調整到根節點的其中一個子節點r2,使得奇偶性再次得到調整
#include#include #define N_max 123456 using namespace std; int n, m, fa[N_max], want[N_max]; int Odd_n, Odd_x, haveOdd[N_max]; vector G[N_max], ans; int getf(int x) { return (fa[x] == x) ? x : fa[x] = getf(fa[x]); } void addedge(int x, int y) { G[x].push_back(y); } void init() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 1; i <= m; i++) { int x, y; scanf("%d%d", &x, &y); int tmpx=getf(x); int tmpy=getf(y); if (tmpx != tmpy) { fa[tmpx] = tmpy; addedge(x, y); addedge(y, x); } } for (int i = 1; i <= n; i++) { scanf("%d", &want[i]); if (want[i]) haveOdd[getf(i)] = 1; } for (int i = 1; i <= n; i++) if (haveOdd[i]) { Odd_n++; Odd_x = i; } } void dfs(int now, int pre) { ans.push_back(now); want[now] ^= 1; for (int i = 0; i < G[now].size(); i++) { int nex = G[now][i]; if (nex == pre) continue; dfs(nex, now); ans.push_back(now); want[now] ^= 1; if (want[nex]) { ans.push_back(nex); want[nex] ^= 1; ans.push_back(now); want[now] ^= 1; } } } void solve() { if (Odd_n == 0) { printf("0\n"); return; } if (Odd_n > 1) { printf("-1\n"); return; } dfs(Odd_x, -1); int x = 0; if (want[Odd_x]) x=1; printf("%d\n", ans.size() - x); for (int i = x; i < ans.size(); i++) printf("%d ", ans[i]); } int main() { init(); solve(); }
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com