题目大意

有\(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练习六十九:urllib爬取练习

    爬取图片,将链接中的图片取出来,并统计一共下载了多少图片 代码: def fetch_pictures(url): headers = {'User-Agent':'Mozilla/5.0 (Wind ...

  2. hibernate 简单入门 配置

    hibernate两个配置文件,一个是类和表的映射关系文件,一个是数据库连接的配置文件 类和表的映射关系 <?xml version="1.0" encoding=" ...

  3. [转]一种可以避免数据迁移的分库分表scale-out扩容方式

    原文地址:http://jm-blog.aliapp.com/?p=590 目前绝大多数应用采取的两种分库分表规则 mod方式 dayofweek系列日期方式(所有星期1的数据在一个库/表,或所有?月 ...

  4. spring 3.0 @ResponseBody注解返回中文问号乱码解决办法

    前几天给公司做项目,很久没接触java项目的我,遇到了一个问题,就是我在利用异步到控制器中查询,然后返回jaon字符串到前台,字符串中包含中文,于是我直接用了@ResponseBody注解,来返回到前 ...

  5. nyoj 983 ——首尾相连数组的最大子数组和——————【最大子串和变形】

    首尾相连数组的最大子数组和 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首 ...

  6. CSS3 -webkit-transform(元素变换)

    CSS3 -webkit-transform(元素变换)   -webkit-transform:none | 类型 类型:scale:缩放,1为原始大小.scale(x).正数放大,负数缩小.属性值 ...

  7. 【linux】基础操作命令

    1.查找文件或者程序位置 root@ROUTER:~# which is hostapd/sbin/hostapd

  8. 监控节点 xml写入数据库 存储过程

    USE [Appserver] GO /****** Object:  StoredProcedure [AppServer].[ImportNodeRelationData]    Script D ...

  9. Sql server 0x80131904

    这是一个比较让人纠结的错误. 背景:添加了网站的分支,要拿一个现有的数据库做一个新的数据库的东东. 首先就是还原备份,然后做代码的修改.然而在登录的时候报了这个错误.0x80131904 什么插入的列 ...

  10. python高阶函数sorted

    原文 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因 ...