码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC_王之盛宴 2015 UESTC Training for Graph Theory<Problem K>

时间:2015-06-12 06:29:14      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

K - 王之盛宴

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

王征战回来了,为了庆祝胜利,王准备请大家吃饭!

于是n个人来到了一家豪华餐厅,这家餐厅有一张长————————长的桌子,每个人只能坐在桌子的南北两侧

pAmBuvAuvuvBuv

如果一种座位安排既满足所有A关系也满足所有B关系,则这种安排是和谐的。

王将会选一侧坐下,然后其他人再坐下,现在王想知道,是否存在一种和谐的座位安排。

Input

npm(2n104,0p104,0m104)

n10

pxyxyAxy

mxyxyBxy

cc=Nc=S

王的名字总是King

Output

如果存在和谐的座位安排,则第一行输出Yes

nsc

sc=Nc=S

座位安排可以按任意次序输出

如果不存在这样的座位安排,输出No

Sample input and output

Sample InputSample Output
4 3 1
King
A
B
C
A B
B C
A C
King A
N
No
4 3 1
King
A
B
C
A B
A C
King A
B C
N
Yes
King N
A S
B N
C N

 

解题思路:

1.将拥有 B 关系的看作连通分量(求连通分量)

 2.跑A关系,保证连通分量中不存在A关系

 3.连通分量缩点,进行二染色

 

注意到B关系我们建边后,跑连通分量可以直接用并查集维护,然后A关系我们依次检查每条边,如果拥有A关系的两个点在一个连通分量中肯定无法构造出解.

之后对连通分量跑二染色即可

 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#define pb push_back

/*
解题报告:
 1.将拥有 B 关系的看作连通分量(求连通分量)
 2.跑A关系,保证连通分量中不存在A关系 
 3.连通分量缩点,进行二染色
*/

typedef long long ll;
using namespace std;

typedef pair < ll , ll > strhash;
typedef pair < ll , ll > spj;
map<strhash,int>new_hash;
set<spj>s;

const int maxn = 3e4 + 50;
const ll p1 = 1526597;
const ll p2 = 2807303;
const ll mod1 = 1e9 + 7;
const ll mod2 = 1e9 + 9;
const char * kingname = "King";

inline strhash GetHashVal(const char * beg)
{
   int len = strlen(beg);
   strhash res;
   ll x1 = 999116156;
   ll x2 = 1515615;
   for(int i = 0 ; i < len ; ++ i)
    {
       x1 = (x1 * p1 + beg[i]) % mod1;
       x2 = (x2 * p2 + beg[i]) % mod2;
    }
   res.first = x1 , res.second = x2;
   return res;
}


vector<int>EA[maxn] , EB[maxn] , EC[maxn];

int n,p,m,set_un[maxn],tot = 0 , colour[maxn];
char kingpos[10];
char kc,oc;
char name[maxn][20];


void dfs(int cur)
{
   set_un[cur] = tot;
   for(int i = 0 ; i < EB[cur].size() ; ++ i)
    {
       int nextnode = EB[cur][i];
       if (set_un[nextnode] == -1)
        dfs(nextnode);
    }
}

bool colourmap(int cur)
{
   for(int i = 0 ; i < EC[cur].size() ; ++ i)
    {
        int nextnode = EC[cur][i];
        if (colour[cur] == colour[nextnode]) 
              return false;
        if (!colour[nextnode])
         {
             colour[nextnode] = 3 - colour[cur];
             if (!colourmap(nextnode))
              return false;
         }
    }
   return true;
}


int main(int argc,char *argv[])
{
  scanf("%d%d%d",&n,&p,&m);
  memset(set_un,-1,sizeof(set_un));
  for(int i = 0 ; i < n ; ++ i)
   {
         scanf("%s",name[i]);
         strhash temp = GetHashVal(name[i]);
         new_hash[GetHashVal(name[i])] = i;
   }
  for(int i = 0 ; i < p ; ++ i)
   {
         char bf1[20] , bf2[20];
         scanf("%s%s",bf1,bf2);
         int p1 = new_hash[GetHashVal(bf1)] , p2 = new_hash[GetHashVal(bf2)];
         EA[p1].pb(p2) , EA[p2].pb(p1);
   }
  for(int i = 0 ; i < m ; ++ i)
   {
         char bf1[20] , bf2[20];
         scanf("%s%s",bf1,bf2);
         int p1 = new_hash[GetHashVal(bf1)] , p2 = new_hash[GetHashVal(bf2)];
         EB[p1].pb(p2) , EB[p2].pb(p1);
   }
  scanf("%s",kingpos);
  for(int i = 0 ; i < n ; ++ i) // 对 B 关系跑连通分量 
   if (set_un[i] == -1)
    {
        dfs(i);
        tot++;
    }
  int check = 1;
  for(int i = 0 ; i < n ; ++ i)
   {
        for(int j = 0 ; j < EA[i].size() ; ++ j)
         {
              int nextnode = EA[i][j];
              if (set_un[i] == set_un[nextnode])
               {
                  check = 0;
             break;
          }
         else
          {
               int p1 = set_un[i] , p2 = set_un[nextnode];
               if (p1 > p2)
                swap(p1,p2);
               spj temp(p1,p2);
               if (s.count(temp))
                continue;
               EC[p1].pb(p2) , EC[p2].pb(p1) ;
               s.insert(temp);
          }
      }
        if (!check) //连通分量中存在 A 关系 
         {
            printf("No\n");
         return 0;    
      }
   }
  memset(colour,0,sizeof(colour));
  for(int i = 0 ; i < tot ; ++ i)
   {
         if (!colour[i])
          {
                colour[i] = 1;
                if (!colourmap(i))
                 {
                    printf("No\n");
              return 0;
           }
       }
   }
  printf("Yes\n");
  kc = kingpos[0];
  if (kc == N)
   oc = S;
  else
   oc = N;
  int kingcolour = colour[set_un[new_hash[GetHashVal(kingname)]]];
  for(int i = 0 ; i < n ; ++ i)
   {
         char out;
         if (colour[set_un[i]] == kingcolour)
          out = kc;
         else
          out = oc;
         printf("%s %c\n",name[i],out);
   }
  return 0;
}

 

UESTC_王之盛宴 2015 UESTC Training for Graph Theory<Problem K>

标签:

原文地址:http://www.cnblogs.com/Xiper/p/4570667.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!