CFgym101627C 题解

关键词:乱搞、AD-Hoc、贪心。

注意到题目里说一个点最多只有两个点是 -1,所以仅保留这些点只能形成一些环和链。

考虑贪心,按实时限制数量从大到小,取能用的中颜色最小的。

然后就过了……

code:

#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
namespace estidi{
	gp_hash_table<int,int>m[200003];
	vector<int>sons[200003];
	int a[200003],cnt[200003],p[200003],vis[200003];
	struct num{
		int id,v;
	};
	bool operator < (num a,num b){
		return a.v<b.v;
	}
	std::priority_queue<num>q;
	int main(){
		int n,mm,k,x,y,b;
		scanf("%d%d%d",&n,&mm,&k);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		for(int i=1;i<=mm;i++){
			scanf("%d%d",&x,&y);
			sons[x].push_back(y);
			sons[y].push_back(x);
			if(a[x]!=-1){
				if(!m[y][a[x]])
					cnt[y]++;
				m[y][a[x]]=1;
			}
			if(a[y]!=-1){
				if(!m[x][a[y]])
					cnt[x]++;
				m[x][a[y]]=1;
			}
		}
//		for(int i=1;i<=n;i++)
//			cerr<<i<<" "<<cnt[i]<<" "<<p[i]<<endl;
		for(int i=1;i<=n;i++)
			if(a[i]==-1)
				q.push({i,cnt[i]});
		while(q.size()){
			x=q.top().id;
			q.pop();
			if(vis[x])
				continue;
			vis[x]=1;
//			cerr<<x<<" "<<cnt[x]<<endl;
			b=1;
			while(m[x][b])
				b++;
			if(b>k){
				printf("No");
				return 0;
			}
			a[x]=b;
			for(int j=0;j<sons[x].size();j++)
				if(a[sons[x][j]]==-1){
					if(!m[sons[x][j]][b])
						cnt[sons[x][j]]++;
					m[sons[x][j]][b]=1;
					q.push({sons[x][j],cnt[sons[x][j]]});
				}
		}
		printf("Yes\n");
		for(int i=1;i<=n;i++)
			printf("%d ",a[i]);
		return 0;
	}
}
int main(){
	estidi::main();
	return 0;
}
posted @ 2025-06-09 19:49  123asdf123  阅读(16)  评论(0)    收藏  举报