zoukankan      html  css  js  c++  java
  • hdu1824 基础2sat

    题意:

    Let's go home

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


    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

    思路:
          基础的2sat,不会的建议看根据对称性解析2sat的那个 ,把队长和两个队员看成基本的一对,然后再把排斥的那个看成排斥的一对,输入的时候记得吧两个队员hash成一个人就行了。


    #include<stdio.h>
    #include<string.h>
    #include<stack>
    
    #define N_node 30000 + 100
    #define N_edge 50000 + 100
    
    using namespace std;
    
    typedef struct
    {
       int to ,next;
    }STAR;
    
    STAR E1[N_edge] ,E2[N_edge];
    int list1[N_node] ,list2[N_node] ,tot;
    int Belong[N_node] ,cnt;
    int mark[N_node] ,id[N_node];
    stack<int>st;
    
    void add(int a ,int b)
    {
       E1[++tot].to = b;
       E1[tot].next = list1[a];
       list1[a] = tot;
       
       E2[tot].to = a;
       E2[tot].next = list2[b];
       list2[b] = tot;
    }
    
    void DFS1(int s)
    {
       mark[s] = 1;
       for(int k = list1[s] ;k ;k = E1[k].next)
       {
          int xin = E1[k].to;
          if(!mark[xin]) DFS1(xin);
       }
       st.push(s);
    }
    
    void DFS2(int s)
    {
       mark[s] = 1;
       Belong[s] = cnt;
       for(int k = list2[s] ;k ;k = E2[k].next)
       {
          int xin = E2[k].to;
          if(!mark[xin]) DFS2(xin);
       }
    }
    
    int main ()
    {
       int n ,m ,i ,a ,b ,c;
       while(~scanf("%d %d" ,&n ,&m))
       {
          for(i = 0 ;i < n ;i ++)
          {
             scanf("%d %d %d" ,&a ,&b ,&c);
             id[a] = i * 2;
             id[b] = id[c] = i * 2 + 1;
          }
          memset(list1 ,0 ,sizeof(list1));
          memset(list2 ,0 ,sizeof(list2));
          tot = 1;
          for(i = 1 ;i <= m ;i ++)
          {
             scanf("%d %d" ,&a ,&b);
             add(id[a] ,id[b]^1);
             add(id[b] ,id[a]^1);
          }
          memset(mark ,0 ,sizeof(mark));
          while(!st.empty())st.pop();
          for(i = 0 ;i < n * 2 ;i ++)
          if(!mark[i]) DFS1(i);
          memset(mark ,0 ,sizeof(mark));
          cnt = 0;
          while(!st.empty())
          {
             int xin = st.top();
             st.pop();
             if(mark[xin]) continue;
             ++cnt;
             DFS2(xin);
          }
          int mk = 0;
          for(i = 0 ;i < n * 2 ;i += 2)
          {
             if(Belong[i]  == Belong[i^1])
             mk = 1;
          }
          mk ? puts("no") : puts("yes");
       }
       return 0;
    }
       
       
    
    
    


  • 相关阅读:
    Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析
    Linq分区操作之Skip,SkipWhile,Take,TakeWhile源码分析
    Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析
    Linq基础操作之Select,Where,OrderBy,ThenBy源码分析
    PAT 1152 Google Recruitment
    PAT 1092 To Buy or Not to Buy
    PAT 1081 Rational Sum
    PAT 1084 Broken Keyboard
    PAT 1077 Kuchiguse
    PAT 1073 Scientific Notation
  • 原文地址:https://www.cnblogs.com/csnd/p/12063020.html
Copyright © 2011-2022 走看看