• uva 10765(割点)


    题意:在一张无向图中去掉每一个点问你连通分支有几个?输出排序前m大的。排序规则是先按连通分支数降序,再按结点标号升序。

    思路:求割点的变通,我们知道在dfs树中除去根节点,若当前节点是割点,那么删去它所得到的连通分支数就是子树的数量+1,而对于根节点就等于子树的数量。所以我们在dfs求割点的时候一旦发现一个子树中的所有点都无法回溯到根节点以前的祖先我们就认为找到了删去它的一个连通分支cut[i]++就可以了。最后有序输出就行了。

    代码如下:

     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 #define MP(a, b) make_pair(a, b)
    11 #define PB(a) push_back(a)
    12 
    13 using namespace std;
    14 
    15 typedef long long ll;
    16 typedef pair<int ,int> pii;
    17 typedef pair<unsigned int, unsigned int> puu;
    18 typedef pair<int ,double> pid;
    19 typedef pair<ll, int> pli;
    20 
    21 const int INF = 0x3f3f3f3f;
    22 const double eps = 1e-6;
    23 const int LEN = 10010;
    24 int n, m, dfn[LEN], cut[LEN], low[LEN], dclock;
    25 vector<int> Map[LEN];
    26 struct cmp{
    27     bool operator() (pii a, pii b){
    28         if(a.second!=b.second)return a.second<b.second;
    29         else return a.first>b.first;
    30     }
    31 };
    32 
    33 void dfs(int u, int fa)
    34 {
    35     int child = 0, v;
    36     dfn[u] = low[u] = dclock++;
    37     for(int i=0, v=Map[u][0]; i<Map[u].size(); i++, v=Map[u][i])
    38         if(dfn[v]<0){
    39             dfs(v,u);
    40             child ++;
    41             low[u] = min(low[u], low[v]);
    42             if((low[v] >= dfn[u] && fa>=0) || (child>1 && fa<0))cut[u]++;
    43         }else if(dfn[v] < dfn[u] && v!=fa) low[u] = min(low[u], dfn[v]);
    44 }
    45 
    46 int main()
    47 {
    48 //    freopen("in.txt", "r", stdin);
    49 
    50     int a, b;
    51     while(scanf("%d%d", &n, &m)!=EOF){
    52         if(!n && !m)break;
    53         for(int i=0; i<LEN; i++)Map[i].clear();
    54         while(scanf("%d%d", &a, &b)!=EOF){
    55             if(a==-1 && b==-1)break;
    56             Map[a].PB(b);
    57             Map[b].PB(a);
    58         }
    59         memset(dfn, -1, sizeof dfn);
    60         memset(cut, 0, sizeof cut);
    61         dclock = 1;
    62         dfs(0, -1);
    63         priority_queue<pii, vector<pii>, cmp> q;
    64         for(int i=0; i<n; i++) q.push(MP(i, cut[i]));
    65         for(int i=0; i<m; i++){
    66             pii nv = q.top(); q.pop();
    67             nv.second++;
    68             printf("%d %d
    ", nv.first, nv.second);
    69         }
    70         printf("
    ");
    71     }
    72     return 0;
    73 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    第15周作业
    软件工程结课作业
    第13次作业--邮箱的正则表达式
    第12次作业
    第10次作业
    Java 8 新的时间日期库
    你还在用if-else吗?
    Java并发编程:4种线程池和缓冲队列BlockingQueue
    ZooKeeper学习第八期——ZooKeeper伸缩性(转)
    ZooKeeper学习第七期--ZooKeeper一致性原理(转)
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3526235.html
Copyright © 2020-2023  润新知