zoukankan      html  css  js  c++  java
  • poj 3177 poj 3352 (边双连通分支)

    题意:告诉你一张无向图,问你构造边双连通分支,需要加最小的边。

    思路:发现这两道题可以用一份代码过掉0.0。真是搞笑,题目意思基本相同。主要就是知道如何构造边双连通分支,原来的双连通分支数记为n那么ans = (n+1)/2这个结论是可以证明的。这里我们就把他记住就好了。至于题目的做法就是统计边双连通分支数,直接上模版。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <stack>
     9 #include <vector>
    10 #include <map>
    11 #define MP(a, b) make_pair(a, b)
    12 #define PB(a) push_back(a)
    13 
    14 using namespace std;
    15 
    16 typedef long long ll;
    17 typedef pair<int ,int> pii;
    18 typedef pair<unsigned int, unsigned int> puu;
    19 typedef pair<int ,double> pid;
    20 typedef pair<ll, int> pli;
    21 
    22 const int INF = 0x3f3f3f3f;
    23 const int maxn = 2010;
    24 const double eps = 1e-6;
    25 const int LEN = 1010;
    26 vector<pii> Map[LEN];
    27 stack<int> s;
    28 int n, m, dclock, low[LEN], dfn[LEN], bri[LEN][2], nbri, block, blong[LEN], ind[LEN];
    29 
    30 void init()
    31 {
    32     memset(dfn, -1, sizeof dfn);
    33     dclock = 1;nbri = block = 0;
    34     while(!s.empty())s.pop();
    35 }
    36 
    37 void dfs(int u, int fa){
    38     int v;
    39     dfn[u] = low[u] = dclock++;
    40     s.push(u);
    41     for(int i=0; i<Map[u].size(); i++){
    42         v = Map[u][i].first;
    43         if(v==fa)continue;
    44         if(dfn[v]<0){
    45             dfs(v, u);
    46             low[u] = min(low[u], low[v]);
    47             if(low[v] > dfn[u]){
    48                 Map[u][i].second = 1;
    49             }
    50         }else if(low[u]>low[v]) low[u] = min(low[u], dfn[v]);
    51     }
    52     if(low[u] == dfn[u]){
    53         block ++;
    54         do{
    55             v = s.top(); s.pop();
    56             blong[v] = block;
    57         }while(v!=u);
    58     }
    59 }
    60 
    61 int main()
    62 {
    63 //    freopen("in.txt", "r", stdin);
    64 
    65     int a, b;
    66     map<int, int> mp;
    67     while(scanf("%d%d", &n, &m)!=EOF){
    68         for(int i=0; i<LEN; i++)Map[i].clear();
    69         for(int i=0; i<m; i++){
    70             scanf("%d%d", &a, &b);
    71             if(mp.count(a*maxn+b))continue;
    72             mp[a*maxn+b] = mp[b*maxn+a] = 1;
    73             Map[a].PB(MP(b, 0));
    74             Map[b].PB(MP(a, 0));
    75         }
    76         init();
    77         dfs(1, -1);
    78         int ans = 0;
    79         //缩点统计度数 由于是无向图所以度数是实际两倍
    80         memset(ind, 0, sizeof ind);
    81         for(int i=1; i<=n; i++){
    82             for(int j=0; j<Map[i].size(); j++){
    83                 int a = i, b = Map[i][j].first;
    84                 if(blong[a]==blong[b])continue;
    85                 ind[blong[a]]++;
    86             }
    87         }
    88 
    89         for(int i=1; i<=block; i++)if(ind[i]==1)ans++;
    90         ans = (ans+1)/2;    //公式
    91         printf("%d
    ", ans);
    92     }
    93     return 0;
    94 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    libv4l 库【转】
    Leap Motion颠覆操控体验的超精致手势追踪技术【转】
    嵌入式Linux下Camera编程--V4L2【转】
    C语言高级应用---操作linux下V4L2摄像头应用程序【转】
    通过摄像头设备采集一帧数据的例子程序(完整版)【转】
    V4L2 camera 驱动 capture测试程序【转】
    v4l2 spec 中文 Ch01【转】
    Video for Linux Two API Specification Revision 2.6.32【转】
    Video for Linux Two API Specification revision0.24【转】
    OpenCV实践之路——人脸检测(C++/Python) 【转】
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3525802.html
Copyright © 2011-2022 走看看