3495: PA2010 Riddle

链接

分析:

  每个点要么建首都,要么不建,并且一个点建了,会导致一些点不能建。所以可以考虑2-sat。

  但是如果在每个郡里两两连边,边数是n^2的。

  考虑用前缀优化。

  S[i]表示对于当前郡,前i个点中是否存在一个首都,A[i]表示i这个点是否建首都。

  1、那么有A[i]=1,则S[i]=1,同样有它的逆否命题:S[i]=0,则A[i]=0。

  2、根据前缀的性质有S[i-1]=1,则S[i]=1,逆否命题:S[i]=0,则S[i-1]=0。

  3、由于每个郡只能有一个首都,所以A[i]=1,则S[i-1]=0,逆否命题:S[i-1]=1,则A[i]=0。

  4、还有满足每条边两边至少一个首都,u=0,则v=1,逆否命题:v=0,则u=1

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
struct Edge{ int to, nxt; } e[N << ];
int head[N], dfn[N], low[N], bel[N], sk[N], top, Index, tot, En;
bool vis[N]; inline void add_edge(int u,int v) {
++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
}
void tarjan(int u) {
low[u] = dfn[u] = ++Index;
sk[++top] = u; vis[u] = ;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
if (vis[v]) low[u] = min(low[u], dfn[v]);
}
if (low[u] == dfn[u]) {
++tot;
do {
vis[sk[top]] = ;
bel[sk[top]] = tot;
top --;
} while (sk[top + ] != u);
}
}
int main() {
int n = read(), m = read(), k = read();
for (int u, v, i = ; i <= m; ++i) {
u = read(), v = read();
add_edge(u + n, v);add_edge(v + n, u);
}
for (int i = ; i <= n; ++i) // A[i]=1,S[i]=1
add_edge(i, i + * n), add_edge(i + * n, i + n);
for (int cnt, now, last, i = ; i <= k; ++i) {
cnt = read(), last = read();
for (int j = ; j <= cnt; ++j) {
now = read();
add_edge(last + * n, now + * n);add_edge(now + * n, last + * n); // S[i-1]=1,S[i]=1
add_edge(now, last + * n); add_edge(last + * n, now + n); // A[i]=1,S[i-1]=0
last = now;
}
}
for (int i = ; i <= (n << ); ++i) if (!dfn[i]) tarjan(i);
for (int i = ; i <= n; ++i) {
if (bel[i] == bel[i + n] || bel[i + * n] == bel[i + * n]) {
puts("NIE"); return ;
}
}
puts("TAK");
return ;
}

最新文章

  1. Android课程---关于下拉列表与状态栏提示的学习
  2. 数据采集实践学习二(C#)
  3. 16-head 简明笔记
  4. Docker 修改默认存储位置
  5. 将组策略中的内容导出至CSV格式
  6. 关于ax+by=c的解x,y的min(|x|+|y|)值问题
  7. Jquery 操作xml 文档的方法
  8. JSON.parse和JSON.stringify 参数详解
  9. tableview 分割线置最左边的解决方法
  10. 前端开发工具—fiddle
  11. VMware vSphere 服务器虚拟化之二十六 桌面虚拟化之View Persona Management
  12. [HMLY]4.CocoaPods详解----制作
  13. Java 读取 .properties 配置文件的几种方式
  14. 快速排序 and 拉格朗日插值查找
  15. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example 1.4 Labeling the Map
  16. 8--Python入门--函数
  17. js动态检测加载 JQ
  18. js指定范围随机整数
  19. SSM实战——秒杀系统之DAO层实体定义、接口设计、mybatis映射文件编写、整合Spring与Mybatis
  20. Flash actionscript3.0 多个setTimeout之间会顺序执行 单线程执行 无法中止

热门文章

  1. 发布MVCIIS报错未能加载文件或程序
  2. MySQL: sql_safe_updates
  3. Struts-config.xml配置文件《action-mappings》元素的详解
  4. 可以简易设置文字内边距的EdgeInsetsLabel
  5. wxpython 编程触发菜单或按钮事件
  6. 铁乐学python_md5校验两个文件的一致性
  7. Outliner大纲式笔记软件介绍
  8. Paxos算法简单陈述
  9. centos6.2/6.3/6.4+nginx+mysql5.5+php5.3.14
  10. kubeadm init 时从本地私有仓库下载镜像