P10298 [CCC 2024 S4] Painting Roads

纯粹的發表於2024-05-24

原題連結

題解

由易到難,先不考慮交替的事情,既然要儘量少的塗色,那麼我最少要塗幾條顏色的邊?(由於圖不一定聯通,這裡先考慮連通圖的情況)

如果一條邊處於一個環內,那麼這個邊就可以不塗色。
所以只要有環我就可以選擇一條邊不塗色,那麼到最後,塗色的邊構成一棵樹

接下來考慮這顆樹能否實現紅藍交替
要滿足紅藍交替,則要滿足對於任意兩點 \(u,v\)\(u \to lca(u,v)\)\(v \to lca(u,v)\) 的邊是交替的,且 \(lca(u,v)\) 通向兩點的第一條邊顏色不同
滿足前半個條件很簡單,按深度奇偶性塗色
一條灰色邊對應一個環,無向圖dfs生成樹一定滿足上述限制,即生成樹中上述情況不可能存在

code

#include<bits/stdc++.h>
using namespace std;

struct node
{
    int id,to;
};
vector<node> G[200005];
int ans[200005];
int vis[200005]={0};
void dfs(int now,int color)
{
    vis[now]=1;
    for(auto next:G[now])
    {
        int id=next.id,to=next.to;
        if(vis[to]) continue;

        ans[id]=color;
        dfs(to,color^1);
    }
}
int main()
{
    memset(ans,-1,sizeof ans);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        G[x].push_back({i,y});
        G[y].push_back({i,x});
    }

    for(int i=1;i<=n;i++)
    {
        if(!vis[i]) dfs(i,1);
    }

    for(int i=1;i<=m;i++)
    if(ans[i]==-1) printf("G");
    else if(ans[i]==0) printf("B");
    else printf("R");
    return 0;
}

相關文章