现在要对一颗树上的边进行染色。如果一个节点连接的边中有大于等于两条颜色相同,则这个节点为不好的点。现在最多只能有 k k k 个不好的点,问最多需要几种颜色可以将树上所有的边进行染色。
比赛的时候前面几题写太慢了,导致没有写到这一题,还是太弱…哭。
我们来考虑这道题如何解决。首先既然有 k k k 个不好的点,一个直接的想法就是让前 k k k 个度数最大的点成为不好的点,然后我们可以发现对于第 k + 1 k+1 k+1 个节点来说,这个节点的度数就是本题所需要的颜色数。
贪心地证明一下,因为最后的颜色数一定等于没被污染的点中度数最大的点的度数,所以我们选择让前 k k k 个点成为不好的点是最优的。然后就是染色了,对于不好的点,所有边染成一个颜色。其余的点,即染成父节点未染过的颜色即可,跑一遍 d f s dfs dfs,循环染色即可。
#include
#include
#include
#include
#include
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
typedef long long ll;
typedef double db;
const db EPS = 1e-9;
using namespace std;
const int N = 2*1e5+1000;
int n,k,tot,head[N],cnt,d[N],vis[N],book[N]; //cnt —— color 数目
struct Edge{
int to,next,color;
}e[2*N];
struct Node{
int id,v;
bool operator < (Node tmp) const {
return v > tmp.v;
}
}t[N];
map<pair<int,int>,int> mp; //mp[make_pair(Node,color)] = 边数
void add(int x, int y){
e[++tot].to = y, e[tot].next = head[x], head[x] = tot, e[tot].color = 0;
e[tot+n-1].to = x, e[tot+n-1].next = head[y], head[y] = tot+n-1, e[tot+n-1].color = 0;
}
int find(int x, int y, int i){
while(1){
if(vis[x]){
if(vis[y]) return i;
else{
if(mp.find(make_pair(y,i)) == mp.end()) return i;
}
}
else{
if(vis[y]){
if(mp.find(make_pair(x,i)) == mp.end()) return i;
}
else{
if(mp.find(make_pair(x,i)) == mp.end() && mp.find(make_pair(y,i)) == mp.end()) return i;
}
}
i = (i+1)%cnt;
if(!i) i = cnt;
}
}
void dfs(int x, int hp){
for(int i = head[x]; i; i = e[i].next){
if(e[i].color) continue;
int y = e[i].to;
e[i].color = find(x,y,hp);
hp = (hp+1)%cnt;
if(hp == 0) hp = cnt;
if(i >= n) e[i-n+1].color = e[i].color;
else e[i+n-1].color = e[i].color;
mp[make_pair(x,e[i].color)] = 1;
mp[make_pair(e[i].to,e[i].color)] = 1;
if(!book[y]) book[y] = 1, dfs(y,hp);
}
}
int main()
{
mp.clear();
scanf("%d%d",&n,&k);
rep(i,1,n) t[i].id = i;
rep(i,1,n-1){
int x,y; scanf("%d%d",&x,&y);
add(x,y);
t[x].v++, t[y].v++;
}
sort(t+1,t+1+n);
rep(i,1,k) vis[t[i].id] = 1;
// rep(i,1,n)
// solve(t[i].id);
cnt = t[k+1].v;
book[t[1].id] = 1;
dfs(t[1].id,1);
printf("%d\n",cnt);
rep(i,1,n-1){
printf("%d",e[i].color);
if(i == n-1) printf("\n");
else printf(" ");
}
return 0;
}