题目链接: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相同不满足条件。
代码:
[code]#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;}