HNOI2019 校園旅行 構造 生成樹 動規

2022-05-20 19:47:13 字數 1395 閱讀 8064

[hnoi2019]校園旅行

最樸素的做法就是點對擴充套件\(o(m^2)\)

發現\(n\)比較小,我們是否能從\(n\)下手減少邊數呢?是肯定的

單獨看乙個顏色的聯通塊,如果是二分圖,我們生產樹和原來的效果相同

如果不是二分圖,是會有乙個環的,在樹上隨便圈乙個自環和原來的效果相同

而看不同顏色的連邊,一定是二分圖,再生產樹就好了

總邊數是\(n\)級的,總複雜度\(o(n^2)\)

#include#includetypedef int ll;

const ll maxn=5009,maxm=500009;

inline ll read()

while(c>='0' && c<='9')

return x*f;

}ll f;

ll visit[maxn],col[maxn],a[maxn],fa[maxn];

ll n,m,q,top;

ll mark[maxn][maxn];

struct edgee[maxm];

ll get_fa(ll x)

struct mpdis[maxm<<1];

ll num;

ll head[maxn];

inline void add(ll u,ll v); head[u]=num;

} void dfs1(ll u,ll c)

ll fx(get_fa(u)),fy(get_fa(v));

if(fx!=fy);

}dfs1(v,3-c);

} }void dfs2(ll u);

fa[fx]=fy;

}dfs2(v);

} }}g1,g2;

std::queueque;

inline void build()

} memset(visit,false,sizeof(visit));

for(ll i=1;i<=n;++i) fa[i]=i;

for(ll i=1;i<=n;++i)

if(!visit[i])

g1.dfs2(i);

for(ll i=1;i<=top;++i)

for(ll u=1;u<=n;++u)); mark[u][u]=true;

for(ll i=g2.head[u];i;i=g2.dis[i].nxt));

mark[v][u]=mark[u][v]=true;

}} }

while(que.size()));}}

}} }

}char s[maxn];

int main()

build();

while(q--)

return 0;

}

HNOI2019 校園旅行

人生第一道黑題祭 本題偏重思維 判斷回文可以考慮它的遞迴定義 只有乙個字元的串是回文串。只有兩個字元的串,如果這兩個字元相同,也是回文串 如果 s 是回文串,那麼在 s 的開頭和末尾插入乙個相同的字元,形成的新串也是回文串。乙個可以想到的方法是設 f 表示從 x 到 y 可不可行 然後 text 列...

HNOI2019 校園旅行

某學校的每個建築都有乙個獨特的編號。一天你在校園裡無聊,決定在校園內隨意地漫步。你已經在校園裡呆過一段時間,對校園內每個建築的編號非常熟悉,於是你情不自禁的把周圍每個建築的編號都記了下來 但其實你沒有真的記下來,而是把每個建築的編號除以 2 取餘數得到 0 或 1,作為該建築的標記,多個建築物的標記...

HNOI2019 校園旅行 DP

給定n nn個點,m mm條邊的圖。每個點有0 1 0 10 1的標號,有q qq個詢問,每次詢問點對 u,v u,v u,v 間是否一條路徑 不一定是簡單路徑 滿足路徑經過的點的標號所形成的串是回文串。n 5000,m 5000000 n leq 5000,m leq 5000000 n 5000...