zoukankan      html  css  js  c++  java
  • poj 2186【Popular Cows】1236【Network of Schools】2553【The Bottom of a Graph】

    三种方法求极大强连通分支的算法,一题一种方法

    poj 2186 求牛被所有其它的牛崇拜的个数,在一个强连通分量里面的牛是互相崇拜的,所以如果这个强连通分支被其它牛崇拜那么这里面的牛都被其它牛崇拜.。。。这一题我用的Tarjan算法

    View Code
     1 #include <iostream>
     2 #include <cstring>
     3 #include <vector>
     4 using namespace std;
     5 
     6 const int maxN = 10000+10;
     7 int low[maxN];
     8 int stack[maxN],top;
     9 int DFN[maxN];
    10 int cnt;
    11 int del[maxN];
    12 vector<int> edge[maxN];
    13 int num;
    14 bool in[maxN];
    15 
    16 void Tarjin(int x)
    17 {
    18     stack[top ++] = x;
    19     low[x] = cnt;
    20     DFN[x] = cnt ++;
    21 
    22     int len = edge[x].size();
    23     for(int i = 0;i < len;i ++)
    24     {
    25         int u = edge[x][i];
    26         if(!DFN[u])
    27         {
    28             Tarjin(u);
    29             if(low[x] > low[u]) low[x] = low[u];
    30         }
    31         else if(!del[u])
    32         {
    33             if(low[x] > DFN[u]) low[x] = DFN[u];
    34         }
    35     }
    36 
    37     if(low[x] == DFN[x])
    38     {
    39         num ++;
    40         do{
    41             del[stack[top-1]] = num;
    42         }while(stack[--top] != x);
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     int n,m;
    49     cin >> n >> m;
    50     for(int i = 0;i < m;i ++)
    51     {
    52         int u,v;
    53         cin >> u >> v;
    54         edge[v].push_back(u);
    55     }
    56     memset(DFN,0,sizeof(DFN));
    57     top = 0;
    58     cnt = 1;
    59     num = 0;
    60 
    61     for(int i = 1;i <= n;i ++)
    62     {
    63         if(!DFN[i])
    64         {
    65             Tarjin(i);
    66         }
    67     }
    68         memset(in,false,sizeof(in));
    69         for(int i = 1;i <= n;i ++)
    70         {
    71             int len = edge[i].size();
    72             for(int j = 0;j < len;j ++)
    73             {
    74                 if(del[i] != del[edge[i][j]])
    75                     in[del[edge[i][j]]] = true;
    76             }
    77         }
    78         int count = 0;
    79         for(int i = 1;i <= num;i ++)
    80         {
    81             if(!in[i])
    82                 count ++;
    83         }
    84         if(count > 1)
    85         {
    86             cout << "0" << endl;
    87             return 0;
    88         }
    89         count = 0;
    90         for(int i = 1;i <= n;i ++)
    91         {
    92             if(!in[del[i]])
    93                 count ++;
    94         }
    95 
    96         cout << count << endl;
    97 
    98     return 0;
    99 }

    poj 1236 http://www.cppblog.com/mythit/archive/2009/05/25/85718.html 用的Kosaraju算法

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <vector>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 const int maxlen = 110;
      8 vector<int> edge[maxlen];
      9 vector<int> redge[maxlen];
     10 bool vis[maxlen];
     11 int twig[maxlen];
     12 int Search[maxlen];
     13 bool in[maxlen],out[maxlen];
     14 int N;
     15 int cnt;
     16 
     17 void dfs1(int i)
     18 {
     19     vis[i] = true;
     20     int len = edge[i].size();
     21     for(int j = 0;j < len;j ++)
     22     {
     23         if(!vis[edge[i][j]])
     24         {
     25             //vis[edge[i][j]] = true;
     26             dfs1(edge[i][j]);
     27         }
     28     }
     29     Search[cnt ++] = i;
     30 }
     31 
     32 void dfs2(int i)
     33 {
     34     vis[i] = true;
     35     twig[i] = cnt;
     36     int len = redge[i].size();
     37 
     38     for(int j = 0;j < len;j ++)
     39     {
     40         int x = redge[i][j];
     41         if(!vis[x])
     42         {
     43             //vis[x] = true;
     44             dfs2(x);
     45         }
     46     }
     47 }
     48 
     49 void Kosaraju()
     50 {
     51     memset(vis,false,sizeof(vis));
     52     cnt = 0;
     53     for(int i = 1;i <= N;i ++)
     54     {
     55         if(!vis[i])
     56             dfs1(i);
     57     }
     58 
     59     cnt = 0;
     60     memset(vis,false,sizeof(vis));
     61     for(int i = N-1;i >= 0;i --)
     62     {
     63         if(!vis[Search[i]])
     64         {
     65             cnt ++;
     66             dfs2(Search[i]);
     67         }
     68     }
     69 
     70 }
     71 
     72 int main()
     73 {
     74     cin >> N;
     75     for(int i = 0;i <= N;i ++)
     76         redge[i].clear();
     77 
     78     for(int i = 1;i <= N;i ++)
     79     {
     80         edge[i].clear();
     81         int x;
     82         while(cin >> x,x)
     83         {
     84             edge[i].push_back(x);
     85             redge[x].push_back(i);
     86         }
     87     }
     88 
     89     Kosaraju();
     90     memset(in,false,sizeof(in));
     91     memset(out,false,sizeof(out));
     92     for(int i = 1;i <= N;i ++)
     93     {
     94         int len = edge[i].size();
     95         for(int j = 0;j < len;j ++)
     96         {
     97             if(twig[i] != twig[edge[i][j]])
     98             {
     99                 out[twig[i]] = true;
    100                 in[twig[edge[i][j]]] = true;
    101             }
    102         }
    103     }
    104     int ans1 = 0,ans2 = 0;
    105     for(int i = 1;i <= cnt;i ++)
    106     {
    107         if(!out[i]) ans1 ++;
    108         if(!in[i]) ans2 ++;
    109     }
    110     if(cnt == 1)
    111     {
    112         cout << "1\n" << "0" << endl;
    113     }
    114     else
    115     {
    116         cout << ans2 << "\n" << max(ans2,ans1) << endl;
    117     }
    118 
    119     return 0;
    120 
    121 }

    poj 2553 一个点如果可以到达其它的点则必须那个点也可以到达这个点,那么不到达那么点,要么互达。。。我用的是Gabow算法

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <vector>
      4 using namespace std;
      5 
      6 const int maxN = 5000+10;
      7 vector<int> edge[maxN];
      8 int stack1[maxN],top1;
      9 int stack2[maxN],top2;
     10 int del[maxN];
     11 int Time[maxN];
     12 //bool vis[maxN];
     13 int cnt;
     14 int num;
     15 int n,m;
     16 bool out[maxN];
     17 int ans[maxN];
     18 
     19 void Gabow(int x)
     20 {
     21     //vis[x] = true;
     22     stack1[top1 ++] = x;
     23     stack2[top2 ++] = x;
     24     Time[x] = cnt ++;
     25     del[x] = 0;
     26 
     27     int len = edge[x].size();
     28     for(int i = 0;i < len;i ++)
     29     {
     30         int u = edge[x][i];
     31         if(!Time[u])
     32         {
     33             Gabow(u);
     34         }
     35         else if(!del[u])
     36         {
     37             while(Time[stack2[top2-1]] > Time[u])
     38             {
     39                 top2 --;
     40             }
     41         }
     42     }
     43 
     44     if(stack2[top2-1] == x)
     45     {
     46         num ++;
     47         top2 --;
     48         do{
     49             del[stack1[top1-1]] = num;
     50         }while(stack1[--top1] != x);
     51     }
     52 }
     53 
     54 int main()
     55 {
     56     while(cin >> n,n)
     57     {
     58         cin >> m;
     59         for(int i = 0;i <= n;i ++)
     60             edge[i].clear();
     61 
     62         for(int i = 0;i < m;i ++)
     63         {
     64             int u,v;
     65             cin >> u >> v;
     66             edge[v].push_back(u);
     67         }
     68 
     69         memset(Time,0,sizeof(Time));
     70         top1 = 0;
     71         top2 = 0;
     72         cnt = 1;
     73         num = 0;
     74         //memset(vis,false,sizeof(vis));
     75         for(int i = 1;i <= n;i ++)
     76         {
     77             if(!Time[i])
     78                 Gabow(i);
     79         }
     80         //memset(vis,false,sizeof(vis));
     81         memset(out,false,sizeof(out));
     82         for(int i = 1;i <= n;i ++)
     83         {
     84             int len = edge[i].size();
     85             for(int j = 0;j < len;j ++)
     86             {
     87                 if(del[i] != del[edge[i][j]])
     88                 {
     89                     out[del[edge[i][j]]] = true;
     90                 }
     91             }
     92         }
     93         int t = 0;
     94         for(int i = 1;i <= n;i ++)
     95         {
     96             if(!out[del[i]])
     97             {
     98                 ans[t ++] = i;
     99             }
    100         }
    101         for(int i = 0;i < t-1;i ++)
    102         {
    103             cout << ans[i] << " ";
    104         }
    105         if(t >= 1)
    106             cout << ans[t-1];
    107         cout << endl;
    108     }
    109 
    110     return 0;
    111 }
  • 相关阅读:
    关于html元素Css样式设置的一点心得(特别是与位置有关的,还有外边距、内边距有关的那些)
    【idea的一个安装细节】是不是使用idea不能连接网络了?
    html中a标签属性parent和self的举例说明
    关于jquery的each的操作;
    superagent中文文档
    mongoose 查询子文档的方法
    Object.prototype.toString.call()进行类型判断
    局部函数的直接引用与调用
    数据模型中某个字段是单选或者多选的定义方式;
    nodejs项目中的路由写法
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2677058.html
Copyright © 2011-2022 走看看