Codeforces 454E&453C Little Pony and Summer Sun Celebration 高妙思路構造題
阿新 • • 發佈:2018-12-15
文章目錄
題意
題解
先判. 稍微思考,發現如果含有要求通過奇數次的點的連通塊的個數超過,因為一條路徑不能穿過連通塊,顯然無解.這個特判一下就行. 剩下的情況肯定有解.我們構造這張圖的任意一棵生成樹,以任意一個要求通過奇數次的點為根對這棵樹開始深度優先搜尋. 我們在走出以為根的子樹時必須要保證走完的整棵子樹通過的次數都滿足要求的奇偶性,因為我們再也不會走進這棵子樹了. 這樣我們對這棵樹跑一次尤拉序,能夠保證子節點都走過奇數次,父節點走過的次數的奇偶性不變. 如果的奇偶性不滿足,就走到它的父親再走回來,這樣和它的子樹都滿足了條件,回去解決它的父節點即可. 注意完之後只有根節點因為沒有父節點能夠幫助它,所以有可能擺脫不了奇偶性不正確的宿命,這時候只要我們幫助它特判一下它的奇偶性是否已經正確,如果不正確,把遍歷路徑的最後一個點刪掉(肯定是根節點)即可. 最後是證明這樣的路徑肯定不超過個點. 很明顯尤拉序的長度不超過,每一個點判父節點增加的路徑長度是,總長不超過. 這樣就可以通過此題了.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rel register ll
#define rec register char
#define gc getchar
//#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<23,stdin),p1==p2)?-1:*p1++)
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
char buf[1<<23],*p1=buf,*p2=buf;
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) pc('-'),x=-x;
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int yuzu=1e5;
typedef int fuko[yuzu|10];
vector<int> lj[yuzu|10],ph;
fuko tov,vis;
#define atp(u) ph.push_back(u),tov[u]^=1
void dfs(int u,int fa=0) {
vis[u]=1,atp(u);
for (int v:lj[u]) if (!vis[v])
dfs(v,u),atp(u);
if (tov[u]&&fa) atp(fa),atp(u);
if (tov[u]) ph.pop_back();
}
bool judge(int n){
int i,hoc=0; // 統計有多少個含奇數度點的連通塊.
static fuko vs;
for (i=1;i<=n;++i) if (!vs[i]) {
int bo=0;
queue<int> q; vs[i]=1,q.push(i);
for (;!q.empty();) {
int u=q.front(); q.pop();
if (tov[u]) bo=1;
for (int v:lj[u]) if (!vs[v]) vs[v]=1,q.push(v);
}
hoc+=bo;
}return hoc<=1;
}
int main() {
int i,n,m,u,v;
read(n),read(m);
for (i=1;i<=m;++i)
u=read(),v=read(),
lj[u].push_back(v),
lj[v].push_back(u);
for (i=1;i<=n;++i) tov[i]=read();
if (!judge(n)) return puts("-1"),0;
for (i=1;i<=n;++i) if (!vis[i]&&tov[i]) dfs(i);
cout<<ph.size()<<endl;
for (auto p:ph) write(p),p32;
}