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 }