题目大意

有\(n\)个城镇被分成了\(k\)个郡,有\(m\)条连接城镇的无向边。要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都。

题目分析

每条边至少有一个端点是首都,每个郡至多一个首都,很容易想到\(2-sat\)判定。

考虑如何建边。我们用\(x\)表示在编号为\(x\)的节点建首都,\(x'\)表示不在该点建首都。

对于一条边的两个端点,若左端点\(l\)不为首都,则右端点\(r\)必为首都;右端点同理,因此\(l\)向\(r'\)连边,\(r\)向\(l'\)连边。

对于同一个郡内的点,若\(a_1\)为首都,则其他点都不能为首都,按照套路我们应取郡内每一个点\(a_i'\)向郡内其他点\(a_j'\)连边。但这样边数是\(n^2\)级别的,难以接受。

于是考虑优化建边。观察同一个郡内的点集\(\{a_1,a_2,...,a_n\}\),我们发现建边时,有许多重复的边\((\)如选择\(a_3\)和\(a_4\)作为首都,那么\(\{a_1,a_2\}\)以及\(\{a_5,a_6\}\)都不能作为首都\()\),因此我们很容易想到前缀与后缀优化连边。

我们新增虚节点\(a_i''\),并且\(a_{i+1}''\)向\(a_{i}''\)连边,\(a_i''\)向\(a_i'\)连边,那么如果选择\(a_i\)作为首都,对于\(a_j(j<i)\)就只需要\(a_i\)向\(a_{i-1}''\)连边即可。这是前缀优化。对于\(a_j(j>i)\)同理用后缀优化即可。

#include <bits/stdc++.h>
using namespace std;
int getint(){
int w=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
return w;
}
const int maxn=4000005;
int n,m,k,h[maxn],dfn[maxn],low[maxn],st[maxn],bel[maxn],scc,sign,top;
bool instack[maxn];
struct edge{int to,next;}e[maxn*5];
void addedge(int x,int y){
static int cnt;
e[++cnt]=(edge){y,h[x]};h[x]=cnt;
}
struct info{int x,i,y;};
void dfs(int x){
static info S[maxn];
static int Top;
int i,y;
call:
dfn[x]=low[x]=++sign;st[++top]=x;instack[x]=1;
for(i=h[x];i;i=e[i].next){
y=e[i].to;
if(!dfn[y]){
S[++Top]=(info){x,i,y};
x=y;goto call;
Return:;
low[x]=min(low[x],low[y]);
}
else if(instack[y])low[x]=min(low[x],dfn[y]);
}
if(low[x]==dfn[x]){
scc++;
for(;;){
int y=st[top--];
instack[y]=0;bel[y]=scc;
if(y==x)break;
}
}
if(Top){x=S[Top].x;i=S[Top].i;y=S[Top].y;Top--;goto Return;}
}
int main(){
// freopen("capital.in","r",stdin);
// freopen("capital.out","w",stdout);
n=getint();m=getint();k=getint();
for(int i=1;i<=m;i++){
int x=getint(),y=getint();
addedge(x+n,y);addedge(y+n,x);
}
for(int i=1;i<=k;i++){
int x=getint();
for(int j=1;j<=x;j++)st[j]=getint();
for(int j=x;j>1;j--)addedge(st[j]+2*n,st[j-1]+2*n);
for(int j=1;j<x;j++)addedge(st[j]+3*n,st[j+1]+3*n);
for(int j=1;j<=x;j++){
if(j>1)addedge(st[j],st[j-1]+2*n);
if(j<x)addedge(st[j],st[j+1]+3*n);
}
}
for(int i=1;i<=n;i++)addedge(i+2*n,i+n),addedge(i+3*n,i+n);
for(int i=1;i<=4*n;i++)if(!dfn[i])dfs(i);
bool flag=0;
for(int i=1;i<=n;i++)if(bel[i]==bel[i+n])flag=1;
if(!flag)puts("TAK");
else puts("NIE");
}

【BZOJ3495】PA2010 Riddle的更多相关文章

  1. 【bzoj 3495】PA2010 Riddle

    Description 有n个城镇被分成了k个郡,有m条连接城镇的无向边.要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都. Input 第一行有三个整数,城镇数n(1<=n&l ...

  2. 【BZOJ】3495: PA2010 Riddle 2-SAT算法

    [题意]有n个城镇被分成了k个郡,有m条连接城镇的无向边.要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都.n,m,k<=10^6. [算法]2-SAT,前后缀优化建图 [题解] ...

  3. 【CF Manthan, Codefest 17 A】Tom Riddle's Diary

    [链接]h在这里写链接 [题意] 在这里写题意 [题解] /* Be careful. 二重循环枚举 */ [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/st ...

  4. Codeforces Round #455 (Div. 2) A. Generate Login【贪心】

    A. Generate Login time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  5. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  6. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  7. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  8. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  9. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

随机推荐

  1. PIE SDK导出图片

    1. 功能简介 导出图片功能可以将制图模板以及视图.绘制元素.制图元素等保存为图片.本示例程序实现了专题制图下导出图片功能. 2. 功能实现说明 2.1导出图片 2.2 实现思路及原理说明 调用IPa ...

  2. linux 运维基础之http协议详解

    引言 这尼玛博客还得自己在这里写,难受一匹本来排版好的...每次都这样嗨....本内容属于借鉴资源,侵权删! HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系 ...

  3. shell 进阶之匹配字符串

      一,操作字符串 1,字符串长度 expr 命令取字符串函数 自带shell函数读取 2,匹配字符串开头字串的长度   !!!!!!!!!!!!$substring是正则表达式.!!!!!!!!! ...

  4. C++的一些编程规范

    新规范的目标: 让代码排错更加简单 程序员专心于业务逻辑 将一些错误交给编译器处理 提高代码可维护性 逐步实现插件化 编码 使用array(QT下用QVarLengthArray)代替和vector代 ...

  5. 初识backbone.js

    backbone,英文意思是:勇气, 脊骨,但是在程序里面,尤其是在backbone后面加上后缀js之后,它就变成了一个框架,一个js库. backbone.js,不知道作者是以什么样的目的来对其命名 ...

  6. jQuery中的DOM操作——《锋利的JQuery》

    jQuery封装了大量DOM操作的API,极大提高了操作DOM节点的效率. 1.查找节点 通过我们上一节介绍了JQuery选择器,可以非常轻松地查找节点元素.不过,这时得到的是jQuery对象,只能使 ...

  7. sql 全局查询

    select * from sysobjects o ,syscomments c where o.id=c.id and text like '%ST_Status%'

  8. 关于如何绕开对通用VMware虚拟机检测的一些收集

    1,用记事本打开虚拟系统镜像文件的配置文件,这个文件扩展名为vmx,比如我的虚拟系统名为XP,那这个文件就叫XP.vmx,然后在其末尾添加这么一句,如下红色部分(注意,虚拟机不能在运行状态添加) mo ...

  9. linux防火墙与端口设置

    1.编辑iptables文件 # sudo vi /etc/sysconfig/iptables 添加如下一行 -A INPUT -p tcp -m state --state NEW -m tcp ...

  10. select, poll, epoll笔记

    看网络通信框架,netty, thrift,java nio等,最后都会通过select, poll, epoll或者socket等进行通信.查了些网页,总结一下.做个笔记 1. Socket单线程阻 ...