zoukankan      html  css  js  c++  java
  • 奶牛议会

    题目link:https://www.luogu.com.cn/problem/P3007

    $2-SAT$ 裸题。

    建图,设第 $i$ 号点表示支持第 $i$ 个法案,第 $i$ $+$ $n$ 号点表示反对第 $i$ 个法案。

    对于每头奶牛的两个条件,因为题目要求必须满足其一,那就对奶牛的两个条件之一取反,并向另一个条件连边,表示如果不满足奶牛的其中一个要求,那必须满足另一个要求。

    跑一遍 $Tarjan$ ,然后判断 $i$ 号点, $i$ $+$ $n$ 号点是否在同一个强连通分量里,如果是的话无论反对还是支持第 $i$ 个法案都会矛盾,无解。

    之后如果有解的话(不满足上一行的情况),那么 $O(n$2$)$暴力判断如果支持了第 $i$ 号法案会不会矛盾,反对会不会矛盾,按情况输出。

    code:

     1 #include <bits/stdc++.h>
     2 #define INF 0x3f3f3f3f
     3 using namespace std;
     4 stack < int > pru;
     5 int n, m, head[2010], low[2010], dfn[2010], col[2010], vis[2010], num, z, color; char s1[10], s2[10];
     6 struct node {int next, to;}stu[8010];
     7 void add(int x, int y) {stu[++num].next = head[x]; stu[num].to = y; head[x] = num;}
     8 void tarjan(int u)
     9 {
    10     dfn[u] = low[u] = ++z; pru.push(u);
    11     for(int i = head[u]; i; i = stu[i].next)
    12     {
    13         int k = stu[i].to;
    14         if(!dfn[k]) tarjan(k), low[u] = min(low[u], low[k]);
    15         else if(!col[k]) low[u] = min(low[u], dfn[k]);
    16     }
    17     if(low[u] == dfn[u])
    18     {
    19         col[u] = ++color;
    20         while(pru.top() != u)
    21             col[pru.top()] = color, pru.pop();
    22         pru.pop();
    23     }
    24     return;
    25 }
    26 void dfs(int u)
    27 {
    28     vis[u] = 1;
    29     for(int i = head[u]; i; i = stu[i].next)
    30     {
    31         int k = stu[i].to;
    32         if(!vis[k]) dfs(k);
    33     }
    34     return;
    35 }
    36 int check(int x)
    37 {
    38     memset(vis, 0, sizeof(vis)); dfs(x);
    39     for(int i = 1; i <= n; ++i)
    40         if(vis[i] && vis[i + n]) return 0;
    41     return 1;
    42 }
    43 int main()
    44 {
    45     scanf("%d %d", &n, &m);
    46     for(int i = 1, x, y, a, b; i <= m; ++i)
    47     {
    48         scanf("%d %s %d %s", &x, s1, &y, s2);
    49         a = (s1[0] == 'Y'), b = (s2[0] == 'Y');
    50         add(a * n + x, !b * n + y), add(b * n + y, !a * n + x);
    51     }
    52     for(int i = 1; i <= 2 * n; ++i)
    53         if(!dfn[i]) tarjan(i);
    54     for(int i = 1; i <= n; ++i)
    55         if(col[i] == col[i + n]) {puts("IMPOSSIBLE"); return 0;}
    56     for(int i = 1, Tr, Fa; i <= n; ++i)
    57     {
    58         Tr = check(i), Fa = check(i + n);
    59         if(Tr && Fa) putchar('?'); else if(Tr) putchar('Y'); else putchar('N');
    60     }
    61     return 0;
    62 }

     

  • 相关阅读:
    SQL Server 优化-执行计划
    SQL Server 开发-语法学习
    MySQL管理_数据库常用命令
    MySQL管理_数据库启动与关闭
    SQL Server DBA日常查询视图_数据库性能视图
    SQL Server DBA性能优化
    MySQL系列 | MySQL高级-08逻辑架构
    工具系列 | Docker基本概念
    PHP系列 | [转] PHP中被忽略的性能优化利器:生成器
    PHP系列 | 代码复用trait的构造函数使用
  • 原文地址:https://www.cnblogs.com/qqq1112/p/14427359.html
Copyright © 2011-2022 走看看