题目大意

有\(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. 多个模块使用python logging

    链接:https://docs.python.org/2/howto/logging-cookbook.html#logging-cookbook 具体的使用方法,请参考如下代码: import lo ...

  2. (转)远程SSH连接服务与基本排错

    远程SSH连接服务与基本排错 原文:https://www.cnblogs.com/chensiqiqi/p/6224474.html#top 1.1 为什么要远程连接Linux系统 在实际的工作场景 ...

  3. Bootstrap 斜体、文本对齐、缩略图、地址、列表等

    目录1.标题2.页面主体3.强调    a.小号文本    b.着重    c.斜体    d.对齐class    e.强调class4.缩略语5.地址6.列表    a.无序列表    b.有序列 ...

  4. java如何实现python的urllib.quote(str,safe='/')

    最近需要将一些python代码转成java,遇到url编码 urllib.quote(str,safe='/') 但java中URLEncoder.encode(arg, Constant.UTF_8 ...

  5. python 对列表去重,并保持列表原来顺序

    mailto = ['cc', 'bbbb', 'afa', 'sss', 'bbbb', 'cc', 'shafa'] addr_to = list(set(mailto)) addr_to.sor ...

  6. sql 创建用户脚本

    USE master go  CREATE LOGIN jiazhuang --用户名 WITH PASSWORD = 'sa', --密码 DEFAULT_DATABASE = JiaZhuan, ...

  7. android JNI学习之一

    执行System.loadLibrary()函数时,VM会反向调用*.so里的JNI_OnLoad()函数.用途有二:1. VM询问此*.so使用的JNI版本编号.2. VM要求*.so做一些初期设定 ...

  8. [LeetCode]22. Generate Parentheses括号生成

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  9. c#winform循环播放多个视频

    环境: vs2015 +winform 首先,vs自带组件很方便,所以,用windowMediaplayer组件,如果做单曲循环播放的话,加个属性: axWindowsMediaPlayer1.set ...

  10. @Component 注解

    @Component a) 初始化的名字默认为类名首字母小写:UserService 在容器中默认为 userService b) 可以指定初始化 bean 的名字:  @Component(valu ...