zoukankan      html  css  js  c++  java
  • poj2186Popular Cows【强连通】【debug两小时】

    这个题我调试两个小时,快调哭了都

    写一下心得

    大意:告诉你一群牛  有n头 (n<10^4)

    然后告诉你m对羡慕关系  如  a牛羡慕b牛

    并且羡慕可以传递  如a羡慕b  b羡慕c  则a羡慕c

    现在问有多少只牛是被所有的牛羡慕的

    分析:我的第一个思路是遍历每个牛 然后从每个牛建立反向边  然后dfs看能否扫到所有的牛  但是这样时间复杂度O(n*(n + e) )  承受不住

    后来想到可以像flody传递闭包那样但是同样时间复杂度承受

    后来想到这个可以强连通一下子

    我们首先想这么一个问题
    对于一个有向无环图  

    满足一个牛被所有牛都羡慕的条件是  :  1  图连通  2  该牛的出度为零(因为他是被所有牛都羡慕的那只  然后如果他再羡慕其他的牛  就会形成环)

    对于本题是有环的   用强连通  进行缩点  变成一个有向无环图  再根据那俩条件进行判定即可

    但是写的时候  首先是我把图中有孤立点这种情况忽略了

    然后就是  脑残的break之后……想起来就心痛啊

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 using namespace std;
      5 
      6 const int maxn = 50005;
      7 
      8 int n, m;
      9 int tot, cnt;
     10 struct Node {
     11     int to, next;
     12 }e[maxn];
     13 int head[maxn];
     14 
     15 void add(int u, int v) {
     16     e[tot].to = v;
     17     e[tot].next = head[u];
     18     head[u] = tot++;
     19 }
     20 int s[maxn];
     21 int ins[maxn];
     22 int sc;
     23 int ans;
     24 int num[maxn];
     25 
     26 int low[maxn], dfn[maxn];
     27 
     28 void init() {
     29     tot = 1;
     30     memset(head, 0, sizeof(head));
     31     memset(low, 0, sizeof(low));
     32     memset(dfn, 0, sizeof(dfn));
     33     memset(ins, 0, sizeof(ins));
     34     memset(num, 0, sizeof(num));
     35     cnt = 1;
     36     sc = 0;
     37     ans = 0;
     38 }
     39 
     40 void dfs(int u) {
     41     s[sc++] = u;
     42     ins[u] = 1;
     43     for(int i = head[u]; i; i = e[i].next) {
     44         int v = e[i].to;
     45         if(!dfn[v]) {
     46             dfn[v] = low[v] = cnt++;
     47             dfs(v);
     48             low[u] = min(low[u], low[v]);
     49         } else if(ins[v] && !num[v]) {
     50             low[u] = min(low[u], dfn[v]);
     51         }
     52     }
     53     if(low[u] == dfn[u]) {
     54         ans++;
     55         int x;
     56         do {
     57             x = s[--sc];
     58             num[x] = ans;
     59             ins[x] = 0;
     60         } while(x != u);
     61     }
     62 
     63 }
     64 int outed[maxn];
     65 
     66 int main() {
     67     int u, v;
     68     while(EOF != scanf("%d %d",&n, &m) ) {
     69         init();
     70         for(int i = 1; i <= m; i++) {
     71             scanf("%d %d",&u, &v);
     72             add(u, v);
     73         }
     74         for(int i = 1; i <= n; i++) {
     75             if(!dfn[i]) {
     76                 dfn[i] = low[i] = cnt++;
     77                 dfs(i);
     78             }
     79         }
     80     //    for(int i = 1; i <= n; i++) {
     81     //        printf("%d ", num[i]);
     82     //    } puts("");
     83         int ans_num = -1;
     84         memset(outed, 0, sizeof(outed));
     85         for(int i = 1; i <= n; i++) {
     86 //            printf("i = %d
    ", i);
     87             if(num[i] == 0) {
     88                 ans_num = 0;
     89                 break;
     90             }
     91             for(int j = head[i]; j ; j = e[j].next) {
     92                 int x = e[j].to;
     93                 if(num[i] != num[x]) {
     94                     outed[num[i]]++;
     95                 }
     96             }
     97         }
     98     //    for(int i = 1; i <= n; i++) {
     99     //        printf("*%d ", outed[i]);
    100     //    } puts("");
    101     //    printf("ans = %d
    ", ans);
    102         int flag = 0;
    103         if(ans_num != 0) {
    104             ans_num = 0;
    105             int ax = 0;
    106             for(int i = 1; i <= ans; i++) {
    107                 if(outed[i] == 0) {
    108                     flag++;
    109                     if(flag >= 2) {
    110                         ans_num = 0;
    111                         break;
    112                     }
    113                     ax = i;
    114                 }
    115             }
    116             if(flag < 2) {
    117                 for(int i = 1; i <= n; i++) {
    118                     if(num[i] == ax) {
    119                         ans_num++;
    120                     }
    121                 }
    122             }
    123         }
    124         printf("%d
    ", ans_num);
    125     }
    126     return 0;
    127 }
    View Code
  • 相关阅读:
    索引优化策略
    mysql列类型选择
    redis安装
    redis相关面试题
    aop动态代理源码分析
    JVM运行时数据区
    redis应用场景
    JPA相关知识
    技术栈
    linux上安装mysql5.6
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/4324539.html
Copyright © 2011-2022 走看看