UVA10765图论+点-双连通分量性质应用

  1 /*
  2 UVA - 10765
  3 算法:如果是割点 那么是多少连同块的公共点那么权值就是多少,否则为一
  4 考点:割点与连通块的关系,ps:我也是通过输出观察连通块,归纳一下才推导的,pps:所以找规律也很重要
  5 补充点:要考虑多个连通分量(指的是dfs得到了)cnt,后来发现题意这是多余的(整个图是连通的)
  6 那么如果图是成几块的,那么valve=出现次数+cnt-1;//可总结规律
  7 坑点:每组输出后有一个空行,坑死偶了。。。
  8 */
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12 #include <math.h>
 13 #include <ctype.h>
 14 #include <string>
 15 #include <iostream>
 16 #include <sstream>
 17 #include <vector>
 18 #include <queue>
 19 #include <stack>
 20 #include <map>
 21 #include <list>
 22 #include <set>
 23 #include <algorithm>
 24 #define maxn 10100
 25 using namespace std;
 26 
 27 struct Edge{int u,v; };
 28 int pre[maxn] , iscut[maxn] ,bccno[maxn] , dfs_clock , bcc_cnt;
 29 vector<int>G[maxn] , bcc[maxn];
 30 stack<Edge> S;
 31 int dfs(int u,int fa){
 32     int lowu = pre[u] = ++dfs_clock;
 33     int child = 0 , ecnt = G[u].size();
 34     for(int i=0;i<ecnt ;i++){
 35         int v = G[u][i];
 36         Edge e = (Edge){u , v};
 37         if(!pre[v]){
 38             S.push(e);
 39             child++;
 40             int lowv = dfs(v ,u);
 41             lowu = min(lowu , lowv);
 42             if(lowv >= pre[u]){
 43                 iscut[u] = 1;
 44                 bcc[++bcc_cnt].clear();
 45                 while(true){
 46                     Edge x = S.top(); S.pop();
 47                     if(bccno[x.u]!=bcc_cnt)
 48                         bcc[bcc_cnt].push_back(x.u) , bccno[x.u] = bcc_cnt;
 49                     if(bccno[x.v]!=bcc_cnt)
 50                         bcc[bcc_cnt].push_back(x.v) , bccno[x.v] = bcc_cnt;
 51                     if(x.u==u && x.v==v) break;
 52                 }
 53             }
 54         }
 55         else if(pre[v] < pre[u] && fa!=v){
 56             S.push(e);
 57             lowu = min(lowu , pre[v]);
 58         }
 59     }
 60     if(fa<0 && child==1) iscut[u] = 0;
 61     return lowu;
 62 }
 63 void find_bcc(int n)//n是定点个数
 64 {
 65     memset(pre,0,sizeof(pre));
 66     memset(iscut,0,sizeof(iscut));
 67     memset(bccno,0,sizeof(bccno));
 68     dfs_clock=bcc_cnt=0;
 69     for(int i=0;i<n;i++)
 70     {
 71         if(!pre[i]) dfs(i,-1);
 72     }
 73 }
 74 struct Node
 75 {
 76     int n;//标号
 77     int v;//权值
 78     bool operator<(const Node &x) const{
 79         if(v==x.v) return n<x.n;else return v>x.v;
 80     }
 81 }node[maxn];
 82 int value[maxn];
 83 int main()
 84 {
 85     int n,m;
 86     while(cin>>n>>m && n!=0)
 87     {
 88         for(int i=0;i<n;i++) G[i].clear();
 89         int u,v;
 90         while(cin>>u>>v && u!=-1)
 91         {
 92             G[u].push_back(v);
 93             G[v].push_back(u);
 94         }
 95         find_bcc(n);
 96 
 97         memset(value,0,sizeof(value));
 98         for(int i=1;i<=bcc_cnt;i++)
 99         for(int j=0;j<bcc[i].size();j++) value[bcc[i][j]]++;
100 
101         for(int i=0;i<n;i++) {
102             node[i].n=i;
103             if (iscut[i])
104             node[i].v=value[i];
105             else node[i].v=1;//千万注意非割点的处理
106         }//要考虑多个连通分量(指的是dfs得到了)的情况,后来发现题意这是多余的
107         sort(node,node+n);
108         for(int i=0;i<m;i++)
109         cout<<node[i].n<<" "<<node[i].v<<endl;
110         // Print a blank line after the output for each set of input.坑了
111         cout<<endl;
112     }
113     return 0;
114 }
原文地址:https://www.cnblogs.com/little-w/p/3570222.html