zoukankan      html  css  js  c++  java
  • [HDOJ6165] FFF at Valentine(强联通分量,缩点,拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6165

    题意:问一个有向图中是否有任意两点可以到达。

    读错题就彻底输了,读成判断是否有任意条路,使得经过所有点并且每条边最多走一次。

    强联通缩点,然后维护拓扑序,假如拓扑序中有两个以上点入度为0,那么这几个点之间就不能互相到达了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 namespace fastIO {
      5     #define BUF_SIZE 20
      6     bool IOerror = 0;
      7     inline char nc() {
      8         static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
      9         if (p1 == pend) {
     10             p1 = buf;
     11             pend = buf + fread(buf, 1, BUF_SIZE, stdin);
     12             if (pend == p1) {
     13                 IOerror = 1;
     14                 return -1;
     15             }
     16         }
     17         return *p1++;
     18     }
     19     inline bool blank(char ch) {
     20         return ch == ' ' || ch == '
    ' || ch == '
    ' || ch == '	';
     21     }
     22     inline void read(int &x) {
     23         char ch;
     24         while (blank(ch = nc()));
     25         if (IOerror)
     26             return;
     27         for (x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
     28     }
     29     #undef BUF_SIZE
     30 };
     31 
     32 const int maxn = 1010;
     33 const int maxm = 6060;
     34 typedef struct Edge {
     35     int u, v, next;
     36     Edge() { next = -1; }
     37 }Edge;
     38 int n, m, cnt;
     39 int head[maxn], ecnt;
     40 Edge edge[maxm];
     41 int bcnt, dindex;
     42 int dfn[maxn], low[maxn];
     43 int stk[maxn], top;
     44 int belong[maxn];
     45 int in[maxn];
     46 bool instk[maxn];
     47 bool vis[maxn];
     48 int f[maxn][maxn];
     49 
     50 void init() {
     51     memset(edge, 0, sizeof(edge));
     52     memset(head, -1, sizeof(head));
     53     memset(instk, 0, sizeof(instk));
     54     memset(dfn, 0, sizeof(dfn));
     55     memset(low, 0, sizeof(low));
     56     memset(belong, 0, sizeof(belong));
     57     memset(in, 0, sizeof(in));
     58     ecnt = top = bcnt = dindex = 0;
     59 }
     60 
     61 void adde(int uu, int vv) {
     62     edge[ecnt].u = uu;
     63     edge[ecnt].v = vv;
     64     edge[ecnt].next = head[uu];
     65     head[uu] = ecnt++;
     66 }
     67 
     68 void tarjan(int u) {
     69     int v = u;
     70     dfn[u] = low[u] = ++dindex;
     71     stk[++top] = u;
     72     instk[u] = 1;
     73     for(int i = head[u]; ~i; i=edge[i].next) {
     74         v = edge[i].v;
     75         if(!dfn[v]) {
     76             tarjan(v);
     77             low[u] = min(low[u], low[v]);
     78         }
     79         else if(instk[v]) low[u] = min(low[u], dfn[v]);
     80     }
     81     if(dfn[u] == low[u]) {
     82         bcnt++;
     83         do {
     84             v = stk[top--];
     85             instk[v] = 0;
     86             belong[v] = bcnt;
     87         } while(v != u);
     88     }
     89 }
     90 
     91 queue<int> q;
     92 
     93 int check() {
     94     while(!q.empty()) {
     95         int u = q.front(); q.pop();
     96         int tot = 0;
     97         for(int v = 1; v <= bcnt; v++) {
     98             if(!f[u][v]) continue;
     99             in[v]--;
    100             if(!in[v]) {
    101                 tot++;
    102                 q.push(v);
    103             }
    104         }
    105         if(tot >= 2) return puts("Light my fire!");
    106     }
    107     return puts("I love you my love and our love save us!");
    108 }
    109 
    110 signed main() {
    111     // freopen("in", "r", stdin);
    112     using namespace fastIO;
    113     int T, u, v;
    114     read(T);
    115     while(T--) {
    116         read(n); read(m);
    117         init();
    118         memset(f, 0, sizeof(f));
    119         for(int i = 0; i < m; i++) {
    120             read(u); read(v);
    121             adde(u, v);
    122         }
    123         for(int i = 1; i <= n; i++) {
    124             if(!dfn[i]) tarjan(i);
    125         }
    126         for(int i = 0; i < ecnt; i++) {
    127             u = belong[edge[i].u], v = belong[edge[i].v];
    128             if(u == v) continue;
    129             if(f[u][v]) continue;
    130             f[u][v] = 1; in[v]++;
    131         }
    132         while(!q.empty()) q.pop();
    133         int cnt = 0;
    134         for(int i = 1; i <= bcnt; i++) {
    135             if(in[i] == 0) {
    136                 q.push(i);
    137                 cnt++;
    138             }
    139         }
    140         (cnt == 1) ? check() : puts("Light my fire!");
    141     }
    142     return 0;
    143 }
  • 相关阅读:
    react路由组件&&非路由组件
    react函数式组件(非路由组件)实现路由跳转
    react使用antd组件递归实现左侧菜单导航树
    【LeetCode】65. Valid Number
    【LeetCode】66. Plus One (2 solutions)
    【LeetCode】68. Text Justification
    【LeetCode】69. Sqrt(x) (2 solutions)
    【LeetCode】72. Edit Distance
    【LeetCode】73. Set Matrix Zeroes (2 solutions)
    【LeetCode】76. Minimum Window Substring
  • 原文地址:https://www.cnblogs.com/kirai/p/7413185.html
Copyright © 2011-2022 走看看