zoukankan      html  css  js  c++  java
  • poj 3683 Priest John's Busiest Day

    题意:给出n个婚礼举行,每个婚礼有两个时间区间,必须选择其中一个,问能不能在每个婚礼都出现且时间不冲突,输出方案。

    一看就是2-sat,但是这道题要输出方案。

    由对称性解2-sat问题 

    http://blog.csdn.net/jarjingx/article/details/8521690

    可以看看论文和博客,有详细讲解。

    简单思路:

    我们用tarjan缩完点之后把图中的边反向。

    首先原图中的边是有传递性的,即选了A必须选B。

    反过来之后,如果A到B有边,那么说明不选A的话一定不能选B,这个很好理解。

    即不选的关系也是有传递性的。

    那么我们在拓扑排序的时候,如果当前点没有标识为不选,那么就选择它,把它的对立点及所有对立点能访问到的点标记为不选。

    这样一定能得到一组合法解。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #define N 2005
      7 #define M 2000005
      8 using namespace std;
      9 int n;
     10 int tot,head[N],ver[M],nxt[M];
     11 void add(int a,int b)
     12 {
     13     tot++;nxt[tot]=head[b];head[b]=tot;ver[tot]=a;return ;
     14 }
     15 int tot2,head2[N],ver2[M],nxt2[M];
     16 void add2(int a,int b)
     17 {
     18     tot2++;nxt2[tot2]=head2[a];head2[a]=tot2;ver2[tot2]=b;return ;
     19 }
     20 int st[N],tim,in[N],dfn[N],low[N],top,be[N],cnt;
     21 void dfs(int x)
     22 {
     23     dfn[x]=low[x]=++tim;
     24     st[++top]=x;
     25     in[x]=1;
     26     for(int i=head[x];i;i=nxt[i])
     27     {
     28         if(!dfn[ver[i]])
     29         {
     30             dfs(ver[i]);
     31             low[x]=min(low[x],low[ver[i]]);
     32         }
     33         else if(in[ver[i]])
     34         {
     35             low[x]=min(low[x],dfn[ver[i]]);
     36         }
     37     }
     38     if(low[x]==dfn[x])
     39     {
     40         cnt++;int y;
     41         do
     42         {
     43             y=st[top--];
     44             be[y]=cnt;
     45             in[y]=0;
     46         }while(y!=x);
     47     }
     48 }
     49 struct node
     50 {
     51     int l,r;
     52 }mr[N];
     53 bool check(int x,int y)
     54 {
     55     if(mr[x].r<=mr[y].l||mr[y].r<=mr[x].l)return 0;
     56     return 1;
     57 }
     58 int rev[N],du[N];
     59 int c[N];
     60 void dffs(int x)
     61 {
     62     if(c[x])return ;
     63     c[x]=-1;
     64     for(int i=head2[x];i;i=nxt2[i])dffs(ver2[i]);
     65 }
     66 queue<int>q;
     67 void tupu()
     68 {
     69     for(int i=1;i<=cnt;i++)if(!du[i])q.push(i);
     70     while(!q.empty())
     71     {
     72         int tmp=q.front();q.pop();
     73         if(c[tmp])continue;
     74         c[tmp]=1;dffs(rev[tmp]);
     75         for(int i=head2[tmp];i;i=nxt2[i])
     76         {
     77             du[ver2[i]]--;
     78             if(!du[ver2[i]])q.push(ver2[i]);
     79         }
     80     }
     81     return ;
     82 }
     83 void pr(int x)
     84 {
     85     printf("%.2d:",x/60);
     86     printf("%.2d ",x%60);
     87 }
     88 int main()
     89 {
     90     scanf("%d",&n);
     91     char s1[10],s2[10];int tmp;
     92     for(int i=1;i<=n;i++)
     93     {
     94         scanf("%s%s",s1,s2);
     95         scanf("%d",&tmp);
     96         mr[2*i].l=(s1[0]-'0')*10+s1[1]-'0';
     97         mr[2*i].l=mr[2*i].l*60+(s1[3]-'0')*10+s1[4]-'0';
     98         
     99         mr[2*i-1].r=(s2[0]-'0')*10+s2[1]-'0';
    100         mr[2*i-1].r=mr[2*i-1].r*60+(s2[3]-'0')*10+s2[4]-'0';
    101         
    102         mr[2*i].r=mr[2*i].l+tmp;
    103         mr[2*i-1].l=mr[2*i-1].r-tmp;
    104     }
    105     for(int i=1;i<=n;i++)
    106     {
    107         for(int j=i+1;j<=n;j++)
    108         {
    109             if(check(2*i,2*j))add(2*i,2*j-1),add(2*j,2*i-1);
    110             if(check(2*i,2*j-1))add(2*i,2*j),add(2*j-1,2*i-1);
    111             if(check(2*i-1,2*j))add(2*i-1,2*j-1),add(2*j,2*i);
    112             if(check(2*i-1,2*j-1))add(2*i-1,2*j),add(2*j-1,2*i);        
    113         }
    114     }
    115     for(int i=1;i<=2*n;i++)if(!dfn[i])dfs(i);
    116     for(int i=1;i<=n;i++)
    117     {
    118         if(be[2*i]==be[2*i-1])
    119         {
    120             puts("NO");
    121             return 0;
    122         }
    123     }
    124     for(int i=1;i<=2*n;i++)
    125     {
    126         for(int j=head[i];j;j=nxt[j])
    127         {
    128             if(be[i]!=be[ver[j]])
    129             {
    130                 add2(be[i],be[ver[j]]);
    131                 du[be[ver[j]]]++;
    132             }
    133         }
    134     }
    135     for(int i=1;i<=n;i++)
    136     {
    137         rev[be[i*2]]=be[2*i-1];
    138         rev[be[i*2-1]]=be[2*i];
    139     }
    140     tupu();
    141     puts("YES");
    142     for(int i=1;i<=n;i++)
    143     {
    144         if(c[be[2*i]]==1)
    145         {
    146             pr(mr[2*i].l);pr(mr[2*i].r);puts("");
    147         }
    148         else
    149         {
    150             pr(mr[2*i-1].l);pr(mr[2*i-1].r);puts("");
    151         }
    152     }
    153     return 0;
    154 }
  • 相关阅读:
    Xcode代码块快捷输入
    Git常用命令
    vim
    MACOX中apache配置
    IOS中实现动画的几种方式
    Swift与OC混合编译
    网络图像加载
    我对互联网的理解
    运行时
    自动布局使用
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6610456.html
Copyright © 2011-2022 走看看