zoukankan      html  css  js  c++  java
  • BZOJ3108 [cqoi2013]图的逆变换

    Description

    定义一个图的变换:对于一个有向图(G=(V, E)),建立一个新的有向图:

    (V'={v_e|e in E})(E'={(v_b, v_e)|b=(u,v), e=(v,w)})(G'=(V', E'))

    也就是说每个边变成一个点,如果边b的终点和边e的起点相同则b到e连一条边。

    现在给定(G'),问是否存在(G)(G')的点数不超过(300)

    Solution

    如果(G')中有((u,w), (v,w))两条边,那么说明(G)(u,v)的终点相同;那么(G')(u,v)连到的点应该是一样的。

    也就是说,如果我在(G')中令(S_i)表示(i)连到的点集,那么(S_i=S_j)(S_icap S_j)必有一成立。

    反之,如果上述条件成立,我可以把所有点按照(S)划分,即可得到(G)中每个点的出边集合;然后容易找出(G)中每个点的入边集合,易证这个(G)是合法的。

    于是bitset求出(S)之后枚举(i,j)判断即可。

    Code

    #include <bitset>
    #include <cstdio>
    const int N = 305;
    std::bitset<N> out[N], zero;
    int main() {
      int T;
      scanf("%d", &T);
      while (T--) {
        int n, m;
        scanf("%d%d", &n, &m);
        zero.reset();
        for (int i = 0; i < n; ++i) out[i].reset();
        for (int x, y; m; --m) {
          scanf("%d%d", &x, &y);
          out[x].set(y);
        }
        bool ok = true;
        for (int i = 0; i < n; ++i)
          for (int j = 0; j < n; ++j)
            ok = ok && ((out[i] & out[j]) == zero || out[i] == out[j]);
        puts(ok ? "Yes" : "No");
      }
      return 0;
    }
    
  • 相关阅读:
    [APIO 2009] Atm
    Codeforces518 D. Ilya and Escalator
    [POJ2096] Collecting bugs
    [ZOJ3329] One Person Game
    [LightOJ1038] Race to 1 Again
    「NOI2003」逃学的小孩
    [HAOI2006] 旅行
    ☆ [POJ2411] Mondriaan's Dream 「状压DP」
    「POJ3311」Hie with the Pie
    「乘法逆元」 学习笔记
  • 原文地址:https://www.cnblogs.com/y-clever/p/8513414.html
Copyright © 2011-2022 走看看