zoukankan      html  css  js  c++  java
  • POJ3177 && POJ3352_加最好的边构成双连通图

    /*
    *State: POJ3177    Accepted    340K    16MS    C++    1877B
    *题目大意:
    *        给出一个无向连通图,判断最少需要加多少条边,才能使得
    *        任意两点之间至少有两条相互"边独立"的道路.注意,可能
    *        含有重边.
    *解题思路:
    *        先缩点,之后形成一棵树,然后求(叶子节点数量+1)/ 2即可。
    */
    View Code
      1 #include <iostream>
      2 #include <vector>
      3 #include <stack>
      4 using namespace std;
      5 
      6 const int MAXN = 5005;
      7 const int MAXE = 10005;
      8 
      9 vector<int> vec[MAXN];
     10 stack<int> S;
     11 int dfn[MAXN], low[MAXN], step;
     12 int id[MAXN], scc;
     13 
     14 void init()
     15 {
     16     while(!S.empty())
     17         S.pop();
     18 
     19     step = 0;
     20     scc = 1;
     21     for(int i = 0; i < MAXN; i++)
     22     {
     23         id[i] = -1;
     24         vec[i].clear();
     25         dfn[i] = low[i] = -1;
     26     }
     27 }
     28 
     29 void addEdge(int u, int v)
     30 {
     31     vec[u].push_back(v);
     32     vec[v].push_back(u);
     33 }
     34 
     35 void tarjan_scc(int n, int father)
     36 {
     37     dfn[n] = low[n] = ++step;
     38     S.push(n);
     39     int flag = 0;
     40     for(unsigned i = 0; i < vec[n].size(); i++)
     41     {
     42         int son = vec[n][i];
     43         if(son == father && !flag)
     44         {
     45             flag = 1;
     46             continue;
     47         }
     48 
     49         if(dfn[son] == -1)
     50         {
     51             tarjan_scc(son, n);
     52             low[n] = min(low[n], low[son]);
     53         }
     54         else
     55             low[n] = min(low[n], dfn[son]);
     56     }
     57 
     58     if(low[n] == dfn[n])
     59     {
     60         int tmp;
     61         do
     62         {
     63             tmp = S.top();
     64             id[tmp] = scc;
     65         //    cout << tmp << " ";
     66             S.pop();
     67         }while(!S.empty() && tmp != n);
     68         scc++;
     69         //cout << endl << "---------------" << endl;
     70     }
     71 }
     72 
     73 void deal_scc(int n, int &sol)
     74 {
     75     int u, v;
     76     int du[MAXN] = {0};
     77     for(int i = 1; i <= n; i++)
     78     {
     79         for(unsigned j = 0; j < vec[i].size(); j++)
     80         {
     81             u = i, v = vec[i][j];
     82             if(id[u] == id[v])
     83                 continue;
     84             else
     85             {
     86                 du[id[v]]++; du[id[u]]++;
     87             }
     88         }
     89     }
     90     int sum = 0;
     91     for(int i = 1; i < scc; i++)
     92     {
     93         if(du[i] == 2)
     94             sum++;
     95     }
     96     sum++;
     97     sol = sum / 2;
     98 }
     99 
    100 int main(void)
    101 {
    102 #ifndef ONLINE_JUDGE
    103     //freopen("in.txt", "r", stdin);
    104 #endif
    105 
    106     int n, m;
    107     while(scanf("%d %d", &n, &m) == 2)
    108     {
    109         init();
    110         int u, v;
    111         for(int i = 0; i < m; i++)
    112         {
    113             scanf("%d %d", &u, &v);
    114             addEdge(u, v);
    115         }
    116         tarjan_scc(1, 1);
    117         int sol;
    118         deal_scc(n, sol);
    119         printf("%d\n", sol);
    120         //cout << "****************" << endl;
    121     }
    122     return 0;
    123 }
    //POJ3352
    //State: POJ3352    Accepted    280K    47MS    C++    1865B
    //题意与上述的题一模一样
    View Code
      1 #include <iostream>
      2 #include <vector>
      3 #include <stack>
      4 using namespace std;
      5 
      6 const int MAXN = 1005;
      7 
      8 vector<int> vec[MAXN];
      9 stack<int> S;
     10 int dfn[MAXN], low[MAXN], step;
     11 int id[MAXN], scc;
     12 
     13 void init()
     14 {
     15     while(!S.empty())
     16         S.pop();
     17 
     18     step = 0;
     19     scc = 1;
     20     for(int i = 0; i < MAXN; i++)
     21     {
     22         id[i] = -1;
     23         vec[i].clear();
     24         dfn[i] = low[i] = -1;
     25     }
     26 }
     27 
     28 void addEdge(int u, int v)
     29 {
     30     vec[u].push_back(v);
     31     vec[v].push_back(u);
     32 }
     33 
     34 void tarjan_scc(int n, int father)
     35 {
     36     dfn[n] = low[n] = ++step;
     37     S.push(n);
     38     int flag = 0;
     39     for(unsigned i = 0; i < vec[n].size(); i++)
     40     {
     41         int son = vec[n][i];
     42         if(son == father && !flag)
     43         {
     44             flag = 1;
     45             continue;
     46         }
     47 
     48         if(dfn[son] == -1)
     49         {
     50             tarjan_scc(son, n);
     51             low[n] = min(low[n], low[son]);
     52         }
     53         else
     54             low[n] = min(low[n], dfn[son]);
     55     }
     56 
     57     if(low[n] == dfn[n])
     58     {
     59         int tmp;
     60         do
     61         {
     62             tmp = S.top();
     63             id[tmp] = scc;
     64         //    cout << tmp << " ";
     65             S.pop();
     66         }while(!S.empty() && tmp != n);
     67         scc++;
     68         //cout << endl << "---------------" << endl;
     69     }
     70 }
     71 
     72 void deal_scc(int n, int &sol)
     73 {
     74     int u, v;
     75     int du[MAXN] = {0};
     76     for(int i = 1; i <= n; i++)
     77     {
     78         for(unsigned j = 0; j < vec[i].size(); j++)
     79         {
     80             u = i, v = vec[i][j];
     81             if(id[u] == id[v])
     82                 continue;
     83             else
     84             {
     85                 du[id[v]]++; du[id[u]]++;
     86             }
     87         }
     88     }
     89     int sum = 0;
     90     for(int i = 1; i < scc; i++)
     91     {
     92         if(du[i] == 2)
     93             sum++;
     94     }
     95     sum++;
     96     sol = sum / 2;
     97 }
     98 
     99 int main(void)
    100 {
    101 #ifndef ONLINE_JUDGE
    102     freopen("in3352.txt", "r", stdin);
    103 #endif
    104 
    105     int n, m;
    106     while(scanf("%d %d", &n, &m) == 2)
    107     {
    108         init();
    109         int u, v;
    110         for(int i = 0; i < m; i++)
    111         {
    112             scanf("%d %d", &u, &v);
    113             addEdge(u, v);
    114         }
    115         tarjan_scc(1, 1);
    116         int sol;
    117         deal_scc(n, sol);
    118         printf("%d\n", sol);
    119         //cout << "****************" << endl;
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    委托和事件的区别和联系(转载
    Captcha验证码识别走向3D化
    3DCaptcha for .net
    委托之异步(转自http://www.cnblogs.com/inforasc/archive/2009/10/21/1587756.html
    static的初始化顺序
    各式各样的验证码
    [SQL优化工具]SQL Tuning for SQL Server(转)
    浅析C#深拷贝与浅拷贝 (转载)
    [orcle] oracle截取字符串的函数substr
    struts2.0的工作原理
  • 原文地址:https://www.cnblogs.com/cchun/p/2641129.html
Copyright © 2011-2022 走看看