先反复地扫(不超过n次),把所有可以确定唯一取法的给确定下来。

然后对于剩下的不能确定的,跑2-SAT。输出可行解时,对于a和¬a,如果a所在的强连通分量序号在¬a之前,则取a,否则不取a。如果a和¬a在同一个强连通分量,则无解。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstring>
using namespace std;
struct data
{
int x1,x2,id;
string s1,s2;
};
data a[1010];
string s1,s2,anss[1010];
int cho[1010];
bool S[100010];
bool __cmp(const data &a,const data &b)
{
return a.x1<b.x1;
}
int n;
vector<int>G[40010],rG[40010],vs;
bool used[40010],will[20010];
int cmp[40010];
void AddEdge(int U,int V)
{
G[U].push_back(V);
rG[V].push_back(U);
}
void dfs(int U)
{
used[U]=1;
for(int i=0;i<G[U].size();++i)
if(!used[G[U][i]])
dfs(G[U][i]);
vs.push_back(U);
}
void rdfs(int U,int k)
{
used[U]=1;
cmp[U]=k;
for(int i=0;i<rG[U].size();++i)
if(!used[rG[U][i]])
rdfs(rG[U][i],k);
}
bool cho2[20010];
int main()
{
// freopen("d.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
cin>>s1>>s2;
a[i].s1=s1.substr(0,3);
a[i].s2=s1.substr(0,2)+s2.substr(0,1);
a[i].x1=(s1[0]-'A')*26*26+(s1[1]-'A')*26+s1[2]-'A';
a[i].x2=(s1[0]-'A')*26*26+(s1[1]-'A')*26+s2[0]-'A';
a[i].id=i;
}
sort(a,a+1+n,__cmp);
int sta;
for(int i=1;i<=n;++i)
{
if(a[i].x1!=a[i-1].x1) sta=i;
if(a[i].x1!=a[i+1].x1 && i>sta)
{
for(int j=sta;j<=i;++j)
{
cho[j]=2;
if(S[a[j].x2])
{
puts("NO");
return 0;
}
S[a[j].x2]=1;
}
}
}
while(1)
{
bool flag=0;
for(int i=1;i<=n;++i)
if(!cho[i])
{
if(S[a[i].x1] && S[a[i].x2])
{
puts("NO");
return 0;
}
else if(S[a[i].x1])
{
flag=1;
cho[i]=2;
S[a[i].x2]=1;
}
else if(S[a[i].x2])
{
flag=1;
cho[i]=1;
S[a[i].x1]=1;
}
else if(a[i].x1==a[i].x2)
{
cho[i]=1;
flag=1;
S[a[i].x1]=1;
}
}
if(!flag)
break;
}
for(int i=1;i<=n;++i)
if(!cho[i])
{
will[a[i].x1]=will[a[i].x2]=1;
AddEdge(a[i].x1,a[i].x2+20000);
AddEdge(a[i].x2,a[i].x1+20000);
}
for(int i=1;i<=20000;++i) if(will[i])
if(!used[i])
dfs(i);
memset(used,0,sizeof(used));
int cnt=0;
for(int i=vs.size()-1;i>=0;--i)
if(!used[vs[i]])
rdfs(vs[i],++cnt);
for(int i=1;i<=20000;++i) if(will[i])
if(cmp[i]==cmp[i+20000])
{
puts("NO");
return 0;
}
else if(cmp[i]>cmp[i+20000])
cho2[i]=1;
for(int i=1;i<=n;++i)
if(cho[i]==1)
anss[a[i].id]=a[i].s1;
else if(cho[i]==2)
anss[a[i].id]=a[i].s2;
else if(cho2[a[i].x1])
anss[a[i].id]=a[i].s1;
else
anss[a[i].id]=a[i].s2;
puts("YES");
for(int i=1;i<=n;++i)
cout<<anss[i]<<endl;
return 0;
}

【2-SAT】Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) D. Innokenty and a Football League的更多相关文章

  1. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) D. Innokenty and a Football League

    地址:http://codeforces.com/contest/782/problem/D 题目: D. Innokenty and a Football League time limit per ...

  2. 【贪心】【DFS】Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) C. Andryusha and Colored Balloons

    从任意点出发,贪心染色即可. #include<cstdio> #include<algorithm> using namespace std; int v[200010< ...

  3. 【三分】Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) B. The Meeting Place Cannot Be Changed

    三分显然,要注意EPS必须设成1e-6,设得再小一点都会TLE……坑炸了 #include<cstdio> #include<algorithm> #include<cm ...

  4. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals)

    Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) 说一点东西: 昨天晚上$9:05$开始太不好了,我在学校学校$9:40$放 ...

  5. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals )D. Innokenty and a Football League(2-sat)

    D. Innokenty and a Football League time limit per test 2 seconds memory limit per test 256 megabytes ...

  6. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals)【A,B,C】

    翻车!翻车! codeforces782A A题: 水. 代码: #include <bits/stdc++.h> using namespace std; typedef long lo ...

  7. 树的性质和dfs的性质 Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) E

    http://codeforces.com/contest/782/problem/E 题目大意: 有n个节点,m条边,k个人,k个人中每个人都可以从任意起点开始走(2*n)/k步,且这个步数是向上取 ...

  8. 2-sat Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) D

    http://codeforces.com/contest/782/problem/D 题意: 每个队有两种队名,问有没有满足以下两个条件的命名方法: ①任意两个队的名字不相同. ②若某个队 A 选用 ...

  9. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) E Underground Lab

    地址:http://codeforces.com/contest/782/problem/E 题目: E. Underground Lab time limit per test 1 second m ...

随机推荐

  1. The XOR Largest Pair [Trie]

    描述 在给定的N个整数A1,A2--AN中选出两个进行xor运算,得到的结果最大是多少? 输入格式 第一行一个整数N,第二行N个整数A1-AN. 输出格式 一个整数表示答案. 样例输入 3 1 2 3 ...

  2. poj1185 炮兵阵地 状压dp

    司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示) ...

  3. SVN 服务器安装及配置(WIN7)

    软件安装包 客户端: 服务端: 安装服务端 不整合 Apache 服务器可以忽略此选项. 安装程序会自动在path下配置好环境变量:D:\Subversion\bin; 查看是否安装成功: C:\Us ...

  4. oracle 数据库图形化工具 sqldeveloper

    1. 安装完成Oracle数据库,点击左下角[开始]菜单,在所有程序中打开[Oracle] 2. 在开始菜单,展开Oracle数据库,安装文件,然后打开[应用程序开发].可以看到[sqldevelop ...

  5. Python基础(2)_if、for、while流程控制

    一.流程控制 1.条件语句 1.1单分支 1.2多分支 条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. a = 5 if a > 2: print('yes') 根据Py ...

  6. KMP算法_模板_C++

    这个博客讲得非常优秀,可惜它是Java版本的 http://blog.csdn.net/yutianzuijin/article/details/11954939/ a 为匹配串,b 为目标串 通俗讲 ...

  7. [Leetcode Week3]Evaluate Division

    Evaluate Division题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/evaluate-division/description/ Desc ...

  8. 利用cron监视后台进程状态

    利用cron监视后台进程状态 http://blog.csdn.net/dyx810601/article/details/72967758 1. 利用cron监视后台进程状态,如果进程死掉或服务器重 ...

  9. Day 14 python 之 字符串练习

    一.字符串总结与练习 #! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "DaChao" # Date: ...

  10. Delphi2007新功能 -- 有限的栈对象

    今天使用Delphi2007,一个误输入,无意中发现Delphi2007的record类型居然能够和TObject一样定义方法和属性,而且不需要调用类似TObject.Create方法就能生成一个re ...