Codeforces Round #647 (Div. 2) - Thanks, Algo Muse! D. Johnny and Contribution(图+贪心)

题目链接:https://codeforces.com/contest/1362/problem/D

题意:给你N个顶点M条边,要给每一个顶点写上一个topic,写这个主题时要根据与该顶点相邻的点的topic中取最小的那个未写过的topic,并且相邻的点不能用相同的topic,问是否存在这样一个序列使得满足题目要求。

思路:比较直接的想法就是从topic为1的优先填,因为前面的topic没填不可能去填后面的,它要基于相邻顶点的最小值的topic,因此我们可以贪心的从1到n去填,满足条件的是该顶点填上了topic的相邻点有i-1个(i为该顶点要填的topic),要注意的是如果两个顶点相邻且所需的topic相同不满足条件。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
vector<int> e[maxn];
vector<int> t[maxn];
vector<int> ans;
int color[maxn],need[maxn];

int main()
{
	int n,m,x,y,c;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x); 
	}
	bool flag=true;
	for(int i=1;i<=n;i++){
		scanf("%d",&c);need[i]=c;
		t[c].push_back(i);
	}
	for(int i=1;i<=n;i++){		//判断是否存在相邻点的topic相同 
		for(int j=0;j<e[i].size();j++){
			if(need[i]==need[e[i][j]]){
				cout<<-1; exit(0);
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<t[i].size();j++){
			int v=t[i][j];map<int,int> mp;c=0;
			for(int k=0;k<e[v].size();k++){
				int w=e[v][k];
				if(color[w]!=0&&!mp[color[w]]){
					mp[color[w]]=1;c++;
				} 
			}
			ans.push_back(v);
			color[v]=i;
			if(c!=i-1){
				flag=false;break;
			} 
		}
	}
	if(!flag) cout<<-1;
	else for(int i=0;i<ans.size();i++) cout<<ans[i]<<" ";
	return 0;	
} 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值