zoukankan      html  css  js  c++  java
  • 【bzoj 3495】PA2010 Riddle

    Description

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

    Input

    第一行有三个整数,城镇数n(1<=n<=10^6),边数m(0<=m<=10^6),郡数k(1<=k<=n)。

    接下来m行,每行有两个整数ai和bi(ai≠bi),表示有一条无向边连接城镇ai和bi。

    接下来k行,第j行以一个整数wj开头,后面是wj个整数,表示第j个郡包含的城镇。

    Output

    若有解输出TAK,否则输出NIE。

    每个点 $x$ 拆成两对点,$x$ 代表选择 $x$ 为首都,$x+n$ 表示不选择 $x$ 为首都,$x+2n$ 表示 $x$ 的前缀已包含首都,$x+3n$表示 $x$ 的前缀不包含首都。

    对于每一条原图中无向边 $(x,y)$ ,因为至少有一个端点为首都,连边 $(x+n,y)$$(y+n,x)$

    对于每一个点 $x$ ,连边 $(x,x+2n)$$(x+3n,x+n)$

    对于每一个点 $x$ 与它的上一个点 $last$ ,连边方式如下:$(last+2n,x+2n)$$(x+3n,last+3n)$$(last+2n,x+n)$$(x,last+3n)$

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define LL long long
     5 using namespace std;
     6 const int N=4e6+5;
     7 int n,m,k,cnt,x,y,last,tim,top,color;
     8 int first[N],dfn[N],low[N],sta[N],c[N];
     9 bool vis[N];
    10 struct edge{int to,next;}e[N*3];
    11 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
    12 int read()
    13 {
    14     int x=0,f=1;char c=getchar();
    15     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    16     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    17     return x*f;
    18 }
    19 void tarjan(int x)
    20 {
    21     low[x]=dfn[x]=++tim;
    22     sta[++top]=x;vis[x]=true;
    23     for(int i=first[x];i;i=e[i].next)
    24     {
    25         int to=e[i].to;
    26         if(!dfn[to])tarjan(to),low[x]=min(low[x],low[to]=min(low[x],low[to]));
    27         else if(vis[to])low[x]=min(low[x],dfn[to]);
    28     }
    29     if(low[x]==dfn[x])
    30     {
    31         color++;
    32         while(sta[top]!=x)vis[sta[top]]=false,c[sta[top--]]=color;
    33         vis[x]=false;c[x]=color;top--;
    34     }
    35 }
    36 bool check()
    37 {
    38     for(int i=1;i<=n;i++)
    39         if(c[i]==c[i+n]||c[i+2*n]==c[i+3*n])return false;
    40     return true;
    41 }
    42 int main()
    43 {
    44     n=read();m=read();k=read();
    45     for(int i=1;i<=m;i++)
    46     {
    47         x=read();y=read();
    48         ins(x+n,y);ins(y+n,x);
    49     }
    50     for(int i=1;i<=k;i++)
    51     {
    52         x=read();last=0;
    53         for(int j=1;j<=x;j++)
    54         {
    55             y=read();
    56             ins(y,y+2*n);ins(y+3*n,y+n);
    57             if(last)
    58             {
    59                 ins(last+2*n,y+2*n);
    60                 ins(y+3*n,last+3*n);
    61                 ins(last+2*n,y+n);
    62                 ins(y,last+3*n);
    63             }
    64             last=y;
    65         }
    66     }
    67     for(int i=1;i<=4*n;i++)if(!dfn[i])tarjan(i);
    68     if(check())printf("TAK");
    69     else printf("NIE");
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    关于工作流程引擎中的岗位的设置的问题
    将要发布的开源CCOA的照片一览
    关于多个checkbox在IE6下自由表单设计器中的兼容问题
    ccflow流程自动发起功能增加,如何按指定的时间触发方式发起流程?
    Windows 如何远程强行关机
    Report bulder
    微软sample and code down web address
    如何查看sql server的死锁情况
    如何读取数据的所有用户表
    复制和数据库镜像
  • 原文地址:https://www.cnblogs.com/zsnuo/p/8940074.html
Copyright © 2011-2022 走看看