zoukankan      html  css  js  c++  java
  • POJ 3683 神父赶婚宴 2-SAT+输出模板

    题意:一个小镇里面只有一个牧师,现在有些新人要结婚,需要牧师分别去主持一个仪式,给出每对新人婚礼的开始时间 s 和结束时间 t ,还有他们俩的这个仪式需要的时间(每对新人需要的时间长短可能不同) d ,牧师可以在婚礼开始的时间 d 内(s 到 s+d)或者是结束前的时间 d 内(t - d 到 t)完成这个仪式。现在问能否给出一种安排,让牧师能完成所有夫妇婚礼的仪式,如果可以,输出一种安排。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long Ull;
    #define MM(a,b) memset(a,b,sizeof(a));
    const double eps = 1e-10;
    const int  inf =0x7f7f7f7f;
    const double pi=acos(-1);
    const int maxn=100+1000;
    
    int n,m,pre[2*maxn],lowlink[2*maxn],dfs_clock,sccno[2*maxn],scc_cnt;
    int opp[2*maxn],st[2*maxn],ed[2*maxn],tt[2*maxn],indeg[2*maxn],color[2*maxn];
    
    struct node{
       int l,r;
    }ne[2*maxn];
    vector<int> G[2*maxn],g[2*maxn];
    stack<int> S;
    
    void tarjan(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        S.push(u);
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(!pre[v])
            {
                tarjan(v);
                lowlink[u]=min(lowlink[u],lowlink[v]);
            }
            else if(!sccno[v])
                lowlink[u]=min(lowlink[u],pre[v]);
        }
    
        if(pre[u]==lowlink[u])
        {
            scc_cnt++;
            for(;;)
            {
                int cur=S.top();S.pop();
                sccno[cur]=scc_cnt;
                if(u==cur) break;
            }
        }
    }
    
    bool find_scc()
    {
        MM(pre,0);
        MM(sccno,0);
        MM(lowlink,0);
        dfs_clock=scc_cnt=0;
    
        for(int i=0;i<2*n;i++)
            if(!pre[i])
              tarjan(i);
    
        for(int i=0;i<2*n;i++)
            if(sccno[i]==sccno[i^1])
                return false;
        return true;
    }
    
    bool inter(node a,node b)
    {
         return a.r>b.l&&a.l<b.r;
    }
    
    void build()
    {
        for(int i=0;i<2*n;i++)
            G[i].clear();
    
        for(int i=0;i<2*n;i++)
           for(int j=i+1;j<2*n;j++)//对任意两个点都进行下判断
               if(inter(ne[i],ne[j]))
              {
                G[i].push_back(j^1);
                G[j].push_back(i^1);
              }
    }
    
    void topsort()
    {
         MM(indeg,0);
         MM(color,0);
         for(int i=1;i<=scc_cnt;i++)
             g[i].clear();
    
         for(int i=0;i<2*n;i++)
         {
             opp[sccno[i]]=sccno[i^1];
             opp[sccno[i^1]]=sccno[i];
         }
    
         for(int u=0;u<2*n;u++)
             for(int i=0;i<G[u].size();i++)
         {
             int a=sccno[u],b=sccno[G[u][i]];
             if(a!=b)
             {
                 indeg[a]++;
                 g[b].push_back(a);
             }
         }
    
         queue<int> q;
         for(int i=1;i<=scc_cnt;i++)
            if(!indeg[i]) q.push(i);
    
         while(q.size())
         {
             int u=q.front();q.pop();
              if(!color[u])
                    {
                        color[u]=1;
                        color[opp[u]]=-1;
                    }
             for(int i=0;i<g[u].size();i++)
             {
                 int v=g[u][i];
                 indeg[v]--;
                 if(!indeg[v]) q.push(v);
             }
         }
    
        for(int i=0;i<n;i++)
          if(color[sccno[i<<1]]==1)
            printf("%02d:%02d %02d:%02d
    ",ne[i<<1].l/60,ne[i<<1].l%60,ne[i<<1].r/60,ne[i<<1].r%60);
          else
           printf("%02d:%02d %02d:%02d
    ",ne[i<<1^1].l/60,ne[i<<1^1].l%60,ne[i<<1^1].r/60,ne[i<<1^1].r%60);
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
           for(int i=0;i<n;i++)
           {
              int a,b,c,d,e;
    
              scanf("%d:%d %d:%d %d",&a,&b,&c,&d,&e);
              ne[i<<1].l=a*60+b;
              ne[i<<1].r=a*60+b+e;
              ne[i<<1^1].l=60*c+d-e;
              ne[i<<1^1].r=60*c+d;
           }//针对每个点,其反点是^关系
    
           build();
    
           if(find_scc())
              {
                  printf("YES
    ");
                  topsort();
              }
           else printf("NO
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    memcache内存估算整理
    yii2-更改默认显示的通用主页
    微信小程序开发工具中快捷键
    微信个人公众号推广
    [微信小程序]编译.wxss出错,2 not found
    [转载]SSH框架搭建详细图文教程
    网址收集
    在IIS上新发布的网站,样式与js资源文件加载不到(资源文件和网页同一个域名下)
    css与html基础收集
    js与jq基础记录
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5493195.html
Copyright © 2011-2022 走看看