zoukankan      html  css  js  c++  java
  • BZOJ3495: PA2010 Riddle

    $n leq 1e6,m leq 1e6$的无向图,每个点属于一个国家(我就说国家咋地),现要求给所有$k$个国家分别选首都,满足:每条边至少一个端点是首都;每个国家有且只有一个首都。

    2-SAT。每个点选和不选。条件一直接满足,条件二边数太多。

    前缀优化建边。来源

     1 //#include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 //#include<time.h>
     5 //#include<complex>
     6 //#include<set>
     7 //#include<queue>
     8 #include<algorithm>
     9 #include<stdlib.h>
    10 using namespace std;
    11 
    12 #define LL long long
    13 int qread()
    14 {
    15     char c; int s=0; while ((c=getchar())<'0' || c>'9');
    16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s;
    17 }
    18 
    19 //Pay attention to '-' , LL and double of qread!!!!
    20 
    21 int n,m,K;
    22 #define maxn 4000011
    23 #define maxm 10000011
    24 struct Edge{int to,next;};
    25 struct Graph
    26 {
    27     Edge edge[maxm]; int first[maxn],le;
    28     Graph() {le=2;}
    29     void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
    30     void insert(int x,int y) {in(x,y); in(y,x);}
    31 }g;
    32 
    33 int bel[maxn],tot,Time,low[maxn],dfn[maxn],sta[maxn],top; bool insta[maxn];
    34 void tarjan(int x)
    35 {
    36     low[x]=dfn[x]=++Time;
    37     sta[++top]=x; insta[x]=1;
    38     for (int i=g.first[x];i;i=g.edge[i].next)
    39     {
    40         Edge &e=g.edge[i];
    41         if (!dfn[e.to]) tarjan(e.to),low[x]=min(low[x],low[e.to]);
    42         else if (insta[e.to]) low[x]=min(low[x],dfn[e.to]);
    43     }
    44     if (low[x]==dfn[x])
    45     {
    46         tot++;
    47         while (sta[top]!=x) insta[sta[top]]=0,bel[sta[top]]=tot,top--;
    48         insta[sta[top]]=0,bel[sta[top--]]=tot;
    49     }
    50 }
    51 bool check()
    52 {
    53     for (int i=1;i<=n;i++) if (bel[i]==bel[i+n] || bel[i+2*n]==bel[i+3*n]) return 0;
    54     return 1;
    55 }
    56 
    57 int main()
    58 {
    59     n=qread(); m=qread(); K=qread();
    60     for (int i=1,x,y;i<=m;i++)
    61     {
    62         x=qread(); y=qread();
    63         g.in(x+n,y); g.in(y+n,x);
    64     }
    65     for (int i=1,x,y,p;i<=K;i++)
    66     {
    67         x=qread(); p=0;
    68         for (int j=1;j<=x;j++)
    69         {
    70             y=qread();
    71             g.in(y,y+2*n); g.in(y+3*n,y+n);
    72             if (p)
    73             {
    74                 g.in(p+2*n,y+2*n);
    75                 g.in(y+3*n,p+3*n);
    76                 g.in(p+2*n,y+n);
    77                 g.in(y,p+3*n);
    78             }
    79             p=y;
    80         }
    81     }
    82     for (int i=1,to=4*n;i<=to;i++) if (!dfn[i]) tarjan(i);
    83     puts(check()?"TAK":"NIE");
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    Mysql主从复制(基于Log)
    Linux系统开机启动流程
    JS的 验证组织机构的合法性
    Linux以下基于TCP多线程聊天室(client)
    浅谈Java集合框架
    疯狂Java学习笔记(72)-----------大话程序猿面试
    Android自己定义View之组合控件 ---- LED数字时钟
    C/C++学习:函数指针
    springmvc+spring+jpa(hibernate)+redis+maven配置
    数组进行多少次OP操作,才干有序
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8934034.html
Copyright © 2011-2022 走看看