您的位置:首页 > 大数据 > 人工智能

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

2016-02-05 23:04 411 查看
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和C
vis[i]=3;
}
for (i=1;i<=n;i++)
{
if (!vis[i])
vis[i]=1;
}
//check
for (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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: