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 }

 

posted @ 2017-03-24 11:12  SD_le  阅读(188)  评论(0编辑  收藏  举报
重置按钮