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 }
  • 相关阅读:
    API开放平台基于accessToken实现
    web记住我功能的实现
    SpringBoot整合AbstractRoutingDataSource实现读写分离
    手写简化版SpringBoot
    mybatisGenerator
    C程序编译执行过程
    用WaveX实现音频文件的录音
    java学习--数组
    Linux学习笔记--vim
    PHP常量总结
  • 原文地址:https://www.cnblogs.com/kirai/p/7413185.html
Copyright © 2011-2022 走看看