bzoj3495 PA2010 Riddle(2-sat+建图优化)

13人阅读 评论(0) 收藏 举报
分类:

我们把每个点当不当首部作为两种选择,得到了一个很显然的2-sat。

但是对于m个点中有且仅有一个点当首都这个条件我们的建边是O(n^2)的,gg

我们考虑如何优化这个建图,如果我们选择第i个点作为首都,则1~i-1都不能当首都,i+1~m也都不能。于是我们想到前缀和后缀和优化,新建2m个点,分别表示1~i有没有首都,i~n有没有首都。

然后我们把这些点之间的限制关系建出来,边数就是O(n)的。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
#define inf 0x3f3f3f3f
#define N 3000010
#define M 12000010
#define ll long long
inline char gc(){
    static char buf[1<<16],*S,*T;
    if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int n,tot=0,m,h[N<<1],num=0,dfn[N<<1],low[N<<1],dfnum=0,bel[N<<1],scc=0;
bool inq[N<<1];stack<int>qq;
struct edge{
    int to,next;
}data[M];
inline void add(int x,int y){
    data[++num].to=y;data[num].next=h[x];h[x]=num;
}
inline void tarjan(int x){
    dfn[x]=low[x]=++dfnum;qq.push(x);inq[x]=1;
    for(int i=h[x];i;i=data[i].next){
        int y=data[i].to;
        if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
        else if(inq[y]) low[x]=min(low[x],dfn[y]);
    }if(low[x]==dfn[x]){
        ++scc;while(1){
            int y=qq.top();qq.pop();inq[y]=0;
            bel[y]=scc;if(y==x) break;
        }
    }
}
int main(){
//  freopen("a.in","r",stdin);
    n=read();m=read();int K=read();
    while(m--){
        int x=read(),y=read();
        add(x<<1|1,y<<1);add(y<<1|1,x<<1);
    }tot=n;
    while(K--){
        m=read();
        for(int i=1;i<=m;++i){
            int x=read(),y=tot+i;
            if(i==1){
                add(x<<1|1,y<<1|1);
            }else{
                add(y<<1|1,(y-1)<<1|1);
                add((y-1)<<1,y<<1);add(x<<1,(y-1)<<1|1);
            }add(x<<1,y<<1);add(y<<1|1,x<<1|1);
            y+=m;
            if(i==m){
                add(x<<1|1,y<<1|1);
            }else{
                add(y<<1|1,(y+1)<<1|1);
                add((y+1)<<1,y<<1);add(x<<1,(y+1)<<1|1);
            }add(x<<1,y<<1);add(y<<1|1,x<<1|1);
        }tot+=m+m;
    }for(int i=2;i<=tot*2+1;++i) if(!dfn[i]) tarjan(i);bool flag=0;
    for(int i=1;i<=tot;++i){
        if(bel[i<<1]==bel[i<<1|1]){flag=1;break;}
    }puts(flag?"NIE":"TAK");
    return 0;
}
查看评论

用ADO进行数据库编程

使用ADO6.1    概述ADO是ActiveX数据对象(ActiveX Data Object),这是Microsoft开发数据库应用程序的面向对象的新接口。ADO访问数据库是通过访问OLE DB...
  • zzh
  • zzh
  • 2000-08-11 16:07:00
  • 1368

【前后缀优化建图+2-SAT】BZOJ3495(PA2010)[Riddle]题解

题目概述有 nn 个点, mm 条边和 KK 个国家(国家里的点已知)。每个国家只能选一个点作为首都,并且要保证最后所有边的两端至少有一个点是首都,问是否存在方案。解题报告每个点是首都或不是首都,只有...
  • zzkksunboy
  • zzkksunboy
  • 2017-07-28 23:37:23
  • 393

【2-SAT+前缀优化建图】BZOJ3495 PA2010 Riddle

题面在这里很典型的2-SAT问题…… 可以对每个点是否为首都建图 考虑一条边(u,v),如果u不是首都,则v必须是。反之亦然。 u′→v,v′→uu'\rightarrow v,v'\right...
  • linkfqy
  • linkfqy
  • 2017-07-28 12:14:32
  • 565

bzoj3495 PA2010 Riddle(2-SAT 前缀优化建边)

bzoj3495 PA2010 Riddle原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3495题意: k个国家,几个城市,m条边。 ...
  • Bfk_zr
  • Bfk_zr
  • 2017-12-10 02:39:35
  • 103

bzoj 3495: PA2010 Riddle 2-sat

bzoj 3495: PA2010 Riddle
  • Rising_shit
  • Rising_shit
  • 2017-12-23 10:49:53
  • 159

[BZOJ3495][PA2010][2-SAT]Riddle

明显的2-SAT模型,但是对于国家的限制,边数是O(n2)O(n^2)的。 可以考虑对有x个城市的国家新建x个结点,第i个结点表示1~i的结点中是否存在首都。那么边数就可以优化到O(n)O(n)了#...
  • Coldef
  • Coldef
  • 2017-04-10 14:38:02
  • 432

[BZOJ]3495: PA2010 Riddle 2-SAT

Description k个国家,几个城市,m条边。 要求每个国家有且仅有一个首都,每条边两端的城市至少要有一个首都。 判断是否有解, 有解输出“TAK”,无解输出”NIE” 1 &amp;...
  • baidu_36797646
  • baidu_36797646
  • 2017-12-24 17:32:54
  • 122

bzoj 3495: PA2010 Riddle(2-SAT)

3495: PA2010 Riddle Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 327  Solved: 115 [Submit][St...
  • Jaihk662
  • Jaihk662
  • 2018-03-01 20:47:38
  • 39

Kids’ Riddle

问题 B: Kids’ Riddle 时间限制: 1 Sec  内存限制: 512 MB 提交: 31  解决: 8 [提交][状态][讨论版] 题目描述 Friends, have you...
  • wanghandou
  • wanghandou
  • 2017-04-17 17:24:17
  • 286

【CF 897C】Nephren gives a riddle

C. Nephren gives a riddle 比赛的时候以为是找规律,想法也跟这个做法差不多了。。就是想太慢了,还差一点想到用递归,确实不太熟练,希望能通过打cf提高一下思维速度。不知...
  • suiguia
  • suiguia
  • 2017-12-03 16:21:53
  • 200
    个人资料
    持之以恒
    等级:
    访问量: 9万+
    积分: 1万+
    排名: 1900
    文章分类
    文章存档
    最新评论