codeforces 1141G Privatization of Roads in Treeland

題目鏈接:http://codeforces.com/contest/1141/problem/G

 

題目大意:

給你一個無向連通圖。每條邊都有顏色,如果存在一個點的臨邊中有超過兩條邊顏色相同,這個點就不好。你要用最少的顏色塗完所有的邊,保證不好的點不超過k。

 

反正吧,我沒想過cfG題會這麼水。不過過的人還真挺少的。(QaQ,比賽沒看這題被F2空間卡崩了)

思路:

先離線處理下。

先記錄所有點的度,然後大到小排序。找到度第k+1大的度。

這個度就是答案。

 

因為我可以認為大於答案的度的點都是不好的;

我們怎麼找到這些點呢?

dfs遍歷。

對於不好的點直接全部畫1就好了。

 

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

//#define int long long
#define MAX 200010
#define fi first
#define se second

map< pair<int,int> ,int>ans;
pair<int,int> x[MAX];
vector <int> y[MAX];
int z[MAX];
bool k[MAX];

bool cmp(const int a,const int b)
{
    return a>b;
}
int Ans;
void dfs(int r,int b)
{
    if(k[r])
    {
        return;
    }
    k[r]=true;

    int len=y[r].size();

    if(len>Ans)
    {
        for(int i=0; i<len; i++)
        {
            if(k[y[r][i]])continue;
            ans[make_pair(r,y[r][i])]=1;
            ans[make_pair(y[r][i],r)]=1;
            dfs(y[r][i],1);
        }
    }
    else{
        bool kk=false;
        int cer=0;
        for(int i=0; i<len; i++)
        {
            if(k[y[r][i]])continue;
            cer++;
            if(cer==b){
                kk=true;
            }
            ans[make_pair(r,y[r][i])]=cer+kk;
            ans[make_pair(y[r][i],r)]=cer+kk;
            dfs(y[r][i],cer+kk);
        }
    }

}
signed main()
{
    ios::sync_with_stdio(false);

    int n,k;

    cin>>n>>k;

    for(int i=1; i<=n-1; i++)
    {
        cin>>x[i].fi>>x[i].se;
        z[x[i].fi]++;
        z[x[i].se]++;
        y[x[i].fi].push_back(x[i].se);
        y[x[i].se].push_back(x[i].fi);
    }

    sort(z+1,z+1+n,cmp);

    Ans=z[k+1];

    cout<<Ans<<endl;
    dfs(1,0);

    for(int i=1;i<n;i++){
        cout<<ans[x[i]]<<" ";
    }
    return 0;
}

 

点赞

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *