cf#AIM Tech Round -C. Graph and String-贪心/ 二分图染色

来源:互联网 发布:毕业论文里的数据作假 编辑:程序博客网 时间:2024/05/23 00:10

http://codeforces.com/contest/624/problem/C


给一个图,要求还原出一个string,字符串只有abc三种字符。

一个字符x会和相同或者在字母表与之相邻的字母连边

即a和ab连,b和abc连,c和bc连

知道了这个后,b是和所有点相连的,度数为n-1

所有度数为n-1的点,都标记为b

然后我们随便找一个不是b的点X,我们标记为C

对于X 会和所有的B,C相连,因为B已经标记过了,那么我们遍历一遍X的所有邻接点,就可以把所有的C标记出来了

剩下的都标记为A


vis[i]=1 ---A
vis[i]=2 ---B
vis[i]=3 ---C

标记完所有点后,我们n^2验证一遍,

任意2个点如果 abs(vis[i]-vis[j]==2)   表明是a-c c-a这种边  需要满足 map[i][j]=0;
如果 abs(vis[i]-[j])<=1  就是其他边 需要满足map[i][j]=1;


枚举每一对点,如果不满足上述条件,no,全部判断完后。yes.



#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;#define ptf(ar1,ar2)  pr__int64f("%I64d:%I64d\n",ar1,ar2);typedef __int64 ll;const ll maxn = 131707+500;int vis[505];int cnt[505];int tm[505][505];int main(){int i,n;int j,m;cin>>n>>m;int x,y;for (i=1;i<=m;i++){scanf("%d%d",&x,&y);tm[x][y]=tm[y][x]=1;cnt[x]++;cnt[y]++;}for (i=1;i<=n;i++){if (cnt[i]==n-1)vis[i]=2;  //为b}int who=0;for (i=1;i<=n;i++){if (vis[i]!=2)  {vis[i]=3;who=i;break;} // C}if (!who){printf("Yes\n");for (i=1;i<=n;i++)printf("b");printf("\n");return 0;}for (i=1;i<=n;i++){if (tm[who][i]&& vis[i]!=2)  //与C相连的只有b和Cvis[i]=3;}for (i=1;i<=n;i++){if (!vis[i])vis[i]=1;}//checkfor (i=1;i<=n;i++){for (j=i+1;j<=n;j++){if (abs(vis[i]-vis[j])==2) //a-c{if (tm[i][j]) {printf("No\n"); return 0  ;}}if (abs(vis[i]-vis[j])<=1)  //a-b  b-c  c-c a-a b-b{if (!tm[i][j]){printf("No\n");return  0 ;}}}}printf("Yes\n");for (i=1;i<=n;i++){if (vis[i]==1) printf("a");else if (vis[i]==2) printf("b");else printf("c");}printf("\n");return 0 ;}


0 0
原创粉丝点击