zoukankan      html  css  js  c++  java
  • 2-sat(tarjan算法)hdu(1824)

    hdu1824

    Let's go home

    Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1291 Accepted Submission(s): 498


    Problem Description
    小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头。
    —— 余光中

    集训是辛苦的,道路是坎坷的,休息还是必须的。经过一段时间的训练,lcy决定让大家回家放松一下,但是训练还是得照常进行,lcy想出了如下回家规定,每一个队(三人一队)或者队长留下或者其余两名队员同时留下;每一对队员,如果队员A留下,则队员B必须回家休息下,或者B留下,A回家。由于今年集训队人数突破往年同期最高记录,管理难度相当大,lcy也不知道自己的决定是否可行,所以这个难题就交给你了,呵呵,好处嘛~,免费**漂流一日。

    Input
    第一行有两个整数,T和M,1<=T<=1000表示队伍数,1<=M<=5000表示对数。
    接下来有T行,每行三个整数,表示一个队的队员编号,第一个队员就是该队队长。
    然后有M行,每行两个整数,表示一对队员的编号。
    每个队员只属于一个队。队员编号从0开始。

    Output
    可行输出yes,否则输出no,以EOF为结束。

    Sample Input
    1 2 0 1 2 0 1 1 2 2 4 0 1 2 3 4 5 0 3 0 4 1 3 1 4

    Sample Output
    yes no
    分析:

    把每个队分成两组,第i个队的两个小分队编号为2*i-1和i*2;然后根据2-sat建边,判断强联通即可即判断 2*i-1和i*2是否在同一个强联通分量

    程序:

    #include"stdio.h"
    #include"string.h"
    #include"stack"
    #define M 3009
    using namespace std;
    stack<int>q;
    int head[M],dfn[M],low[M],belong[M],use[M],t,n,index,num,cnt[M];
    struct st
    {
         int u,v,next;
    }edge[M*10];
    void init()
    {
         t=0;
         memset(head,-1,sizeof(head));
    }
    void add(int u,int v)
    {
         edge[t].u=u;
         edge[t].v=v;
         edge[t].next=head[u];
         head[u]=t++;
    }
    void tarjan(int u)
    {
         dfn[u]=low[u]=++index;
         q.push(u);
         use[u]=1;
         int i;
         for(i=head[u];i!=-1;i=edge[i].next)
         {
              int v=edge[i].v;
              if(!dfn[v])
              {
                   tarjan(v);
                   low[u]=min(low[u],low[v]);
              }
              else if(use[v])
              {
                   low[u]=min(low[u],dfn[v]);
              }
         }
         if(dfn[u]==low[u])
         {
              int vv;
              num++;
              do
              {
                   vv=q.top();
                   belong[vv]=num;
                   q.pop();
                   use[vv]=0;
              }while(u!=vv);
         }
    }
    void solve()
    {
         index=num=0;
         memset(dfn,0,sizeof(dfn));
         memset(use,0,sizeof(use));
         for(int i=1;i<=n;i++)
         {
              if(!dfn[i])
                   tarjan(i);
         }
    }
    int main()
    {
         int T,m,i;
         while(scanf("%d%d",&T,&m)!=-1)
         {
              for(i=1;i<=T;i++)
              {
                   int a,b,c;
                   scanf("%d%d%d",&a,&b,&c);
                   cnt[a]=2*i-1;
                   cnt[b]=cnt[c]=2*i;
              }
              n=T*2;
              init();
              while(m--)
              {
                   int a,b;
                   scanf("%d%d",&a,&b);
                   if(cnt[a]!=cnt[b])
                   {
                        if(cnt[a]&1&&cnt[b]&1)
                        {
                             add(cnt[a],cnt[b]+1);
                             add(cnt[b],cnt[a]+1);
                        }
                        if(cnt[a]%2==0&&cnt[b]%2==0)
                        {
                             add(cnt[a],cnt[b]-1);
                             add(cnt[b],cnt[a]-1);
                        }
                        if(cnt[a]%2==0&&cnt[b]&1)
                        {
                             add(cnt[a],cnt[b]+1);
                             add(cnt[b],cnt[a]-1);
                        }
                        if(cnt[a]&1&&cnt[b]%2==0)
                        {
                             add(cnt[a],cnt[b]-1);
                             add(cnt[b],cnt[a]+1);
                        }
                   }
              }
              solve();
              int flag=0;
              for(i=1;i<=T;i++)
              {
                   if(belong[i*2-1]==belong[i*2])
                   {
                        flag++;
                        break;
                   }
              }
              if(flag)
                   printf("no
    ");
              else
                   printf("yes
    ");
         }
    }
    


  • 相关阅读:
    使用MobaXterm远程连接Ubuntu,启动Octave,界面不能正常显示
    ABP .Net Core 日志组件集成使用NLog
    ABP .Net Core Entity Framework迁移使用MySql数据库
    ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
    阿里云 Angular 2 UI框架 NG-ZORRO介绍
    Visual Studio 2019 Window Form 本地打包发布猫腻
    VS Code + NWJS(Node-Webkit)0.14.7 + SQLite3 + Angular6 构建跨平台桌面应用
    ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed
    ABP .Net Core To Json序列化配置
    .Net EF Core数据库使用SQL server 2008 R2分页报错How to avoid the “Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.”
  • 原文地址:https://www.cnblogs.com/mypsq/p/4348255.html
Copyright © 2011-2022 走看看