标签:include dfs i++ return 不重复 就是 ycm 维护 一个
<题目链接>
题目大意:
给定一棵树,给每条边染色,如果一个结点的两条边是相同颜色的,那么这个结点就是不满意的。
现在要求颜色最少的染色数,使得不满意结点数量<=k。
解题分析:
首先,贪心地想,因为题目允许有最多k个不满意的点,所以我们将所有点的度数从大到小排个序,度数第k+1大的点的度数就是最少的染色数。然后,主要就是给出染色的方案了,我们可以用DFS对整棵树的所有边进行染色,同时,染色的过程中,还要尽可能地保证所有节点周围的边所染的颜色都不重复。所以我让每个节点都维护了一个mark值,然后在染色过程中,贪心地将当前到达的边染成mark++的颜色,如果mark值大于染色数,说明这个节点只能是不满意的,这个时候就将mark置0,继续进行染色。
#include <bits/stdc++.h> using namespace std; const int N = 2e5+5; #define pb push_back int n,k; struct Edge{int s,e;}e[N]; struct Edg {int to,loc;}; int deg[N],col[N],mark[N]; int colnum; vector<Edg>G[N]; bool mycmp(int a,int b){ return a>b; } void dfs(int u){ //在DFS过程中,贪心地对所有节点周围的边染色 for(int i=0;i<G[u].size();i++){ int v=G[u][i].to; int id=G[u][i].loc; if(col[id])continue; col[id]=mark[u]+1;mark[u]++; //贪心地将u节点连向子节点的边全部优先染成不同颜色 if(mark[u]>=colnum)mark[u]=0; //如果出现冲突的话,就将这个点的其它连接子节点的边随便染成一种颜色 mark[v]=col[id];if(mark[v]>=colnum)mark[v]=0; //注意将下一个点也要做标记,这样做标记的目地就是尽可能的让一个节点周围的所有边不重复染色 dfs(v); } } int main(){ scanf("%d%d",&n,&k); for(int i=1;i<n;i++){ int u,v;scanf("%d %d",&u,&v); deg[u]++,deg[v]++; e[i]=Edge{u,v}; G[u].pb(Edg{v,i}); G[v].pb(Edg{u,i}); } sort(deg+1,deg+1+n,mycmp); colnum=deg[k+1]; //得到第k+1个节点的度 printf("%d\n",colnum); dfs(1); for(int i=1;i<n;i++)printf("%d ",col[i]); }
CodeForces 1141G Privatization of Roads in Treeland (贪心+DFS染色)
标签:include dfs i++ return 不重复 就是 ycm 维护 一个
原文地址:https://www.cnblogs.com/00isok/p/10568988.html