zoukankan      html  css  js  c++  java
  • hdu 4115(2-SAT) 2011 成都现场赛E题

    题意:两个人玩剪刀石头布,你知道对手出拳的序列(就是每一步出哪个)给你两种限制,i与j相同和不相同。你赢的条件是你不能输给对方一次,问你能不能赢。

    思路:典型的2-SAT题目,对于每次猜拳,排除你会输的那一次然后就只剩两个选择了,接下来就是分类讨论。

    我们定义第一个能出的为真,另一个为假

    首先分成 i次 与j次不能出的相同,那么 

      a b 1 表示 a^b = 1

      a b 0 表示 a^b = 0

    然后是不同的,那么

      对于a b 1情况

        a b 出那个已经知道了

      a b 0情况

        !a->b ^ !b->a  都能出的为假

        a->!b ^ b->!a  都能出的为真

    代码如下:

      1 /**************************************************
      2  * Author     : xiaohao Z
      3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
      4  * Last modified : 2014-03-22 16:59
      5  * Filename     : hdu_chengdu2.cpp
      6  * Description     : 
      7  * ************************************************/
      8 
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <cmath>
     14 #include <algorithm>
     15 #include <queue>
     16 #include <stack>
     17 #include <vector>
     18 #include <set>
     19 #include <map>
     20 #define MP(a, b) make_pair(a, b)
     21 #define PB(a) push_back(a)
     22 
     23 using namespace std;
     24 typedef long long ll;
     25 typedef pair<int, int> pii;
     26 typedef pair<unsigned int,unsigned int> puu;
     27 typedef pair<int, double> pid;
     28 typedef pair<ll, int> pli;
     29 typedef pair<int, ll> pil;
     30 
     31 const int INF = 0x3f3f3f3f;
     32 const double eps = 1E-6;
     33 const int LEN = 100000+10;
     34 int n, m, chu[LEN][4], vis[LEN], sccn[LEN];
     35 vector<int> Map[LEN], rMap[LEN], vs;
     36 
     37 void dfs(int v){
     38     vis[v] = 1;
     39     for(int i=0; i<Map[v].size(); i++) if(!vis[Map[v][i]]) dfs(Map[v][i]);
     40     vs.PB(v);
     41 }
     42 
     43 void rdfs(int v, int k){
     44     vis[v] = 1;
     45     sccn[v] = k;
     46     for(int i=0; i<rMap[v].size(); i++) if(!vis[rMap[v][i]]) rdfs(rMap[v][i], k);
     47 }
     48 
     49 int scc(){
     50     memset(vis, 0, sizeof vis);
     51     vs.clear();
     52     for(int v=0; v<2*n; v++) if(!vis[v]) dfs(v);
     53     memset(vis, 0, sizeof vis);
     54     int k = 0;
     55     for(int i=vs.size()-1; i>=0; i--) if(!vis[vs[i]]) rdfs(vs[i], k++);
     56     return k;
     57 }
     58 
     59 bool twosat(){
     60     scc();
     61 //    for(int i=0; i<2*n; i++)cout << sccn[i] << ' ';
     62 //    cout << endl;
     63     for(int i=0; i<2*n; i+=2){
     64         if(sccn[i] == sccn[i^1]){
     65             //cout << i << endl;
     66             return false; 
     67         }    
     68     }
     69     return true;
     70 }
     71 
     72 void add(int a, int b){
     73     Map[a].PB(b);
     74     rMap[b].PB(a);
     75 }
     76 
     77 void addNot(int a, int b){
     78     a*=2; b*=2;
     79     add(a, b^1);
     80     add(b^1, a);
     81     add(b, a^1);
     82     add(a^1, b);
     83 }
     84 
     85 void addYes(int a, int b){
     86     a*=2; b*=2;
     87     add(a, b);
     88     add(b, a);
     89     add(a^1, b^1);
     90     add(b^1, a^1);
     91 }
     92 
     93 void addSame(int a){
     94     add(a^1, a);
     95 }
     96 
     97 void addNotSame(int a, int b){
     98     add(a, b^1);
     99     add(b, a^1);
    100 }
    101 
    102 int main()
    103 {
    104 //    freopen("in.txt", "r", stdin);
    105     
    106     int T, a, b, c;
    107     scanf("%d", &T);
    108     for(int kase=1; kase<=T; kase++){
    109         for(int i=0; i<LEN; i++) Map[i].clear();
    110         for(int i=0; i<LEN; i++) rMap[i].clear();
    111         memset(chu, 0, sizeof chu);
    112         scanf("%d%d", &n, &m);
    113         for(int i=0; i<n; i++){
    114             int tmp;
    115             scanf("%d", &tmp);
    116             chu[i][0] = tmp;
    117             chu[i][(tmp)%3+1] = 1;
    118         }
    119         for(int i=0; i<m; i++){
    120             scanf("%d%d%d", &a, &b, &c);
    121             a--; b--;
    122             if(chu[a][0] == chu[b][0]){
    123                 if(c == 1) addNot(a, b);
    124                 else addYes(a, b);
    125             }else{
    126                 int fa = -1, fb = -1;
    127                 for(int j=1; j<4; j++){
    128                     if(!chu[a][j]) fa++;
    129                     if(!chu[b][j]) fb++;
    130                     if(chu[a][j] == chu[b][j] && chu[b][j] == 0) break;
    131                 }
    132                 if(c == 0){
    133                     addSame((2*a)^fa);
    134                     addSame((2*b)^fb);
    135                 }else{
    136                     addNotSame((2*a)^fa, (2*b)^fb);
    137                 }
    138             }
    139         }
    140         printf("Case #%d: ", kase);
    141         if(twosat())printf("yes
    ");
    142         else printf("no
    ");
    143     }
    144     return 0;
    145 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    HDU5418.Victor and World(状压DP)
    POJ2686 Traveling by Stagecoach(状压DP)
    POJ3254Corn Fields(状压DP)
    HDU5407.CRB and Candies(数论)
    CodeForces 352D. Jeff and Furik
    CodeForces 352C. Jeff and Rounding(贪心)
    LightOj 1282 Leading and Trailing
    Ural 1057. Amount of Degrees(数位DP)
    HDU 2089 不要62 (数位DP)
    HDU5366 The mook jong (DP)
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3618269.html
Copyright © 2011-2022 走看看