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 }