UESTC - 900 方老师炸弹 —— 割点
题目链接:https://vjudge.net/problem/UESTC-900
方老师炸弹
Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
方老师准炸毁学校,学校可以被看做是一个图包含N个顶点和M条边(顶点从0开始标号),方老师发明了一个方老师炸弹。
这个炸弹可以炸毁某一个节点和与这个节点相连的所有边。但是方老师现在很彷徨,他想使得使用了一个炸弹之后学校炸成更多的联通块。
方老师想知道把学校炸成尽量多块的放置点的前K个顶点是哪些,这些点可以被把学校炸成多少个联通块?
Input
- 多组数据,
EOF
结束。 - 第1行:N和M和K
- 第2到第M+1行:每一行2个数Ui和Vi,表示Ui到Vi之间有一条边。
Output
K行,每行2个数Posi,Ci,用空格隔开,表示在Posi点放置炸弹可以把学校炸成Ci块。如果对于不同的点可以把学校炸成相同多块,优先输出编号小的顶点。
每组数据后面输出一个空行
Sample input and output
Sample Input | Sample Output |
---|---|
8 8 4 0 4 1 2 2 3 2 4 3 5 3 6 3 7 6 7 |
2 3 3 3 4 2 0 1 |
Hint
K≤N≤10000,M≤100000
题解:
割点的裸题。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 typedef long long LL; 7 const int INF = 2e9; 8 const LL LNF = 9e18; 9 const int mod = 1e9+7; 10 const int maxn = 10000+10; 11 12 int n, m, k,vis[maxn], low[maxn], dfn[maxn], stamp; 13 14 struct node //q[i].x为删除结点i后增加的连通块 15 { 16 int x, id; 17 bool operator<(const node &a)const{ 18 if(x==a.x) return id<a.id; 19 return x>a.x; 20 } 21 }q[maxn]; 22 23 struct 24 { 25 int v, next; 26 }edge[maxn*10]; 27 int tot, head[maxn]; 28 29 void add(int u, int v) 30 { 31 edge[tot].v = v; 32 edge[tot].next = head[u]; 33 head[u] = tot++; 34 } 35 36 void dfs(int u, int pre) 37 { 38 dfn[u] = low[u] = ++stamp; 39 for(int i = head[u]; i!=-1; i = edge[i].next) 40 { 41 int v = edge[i].v; 42 if(v==pre) continue; 43 if(!dfn[v]) 44 { 45 dfs(v, u); 46 low[u] = min(low[u], low[v]); 47 if(low[v]>=dfn[u]) 48 q[u].x++; 49 } 50 else 51 low[u] = min(low[u],dfn[v]); 52 } 53 } 54 55 int main() 56 { 57 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 58 { 59 memset(vis,0, sizeof(vis)); 60 memset(low,0, sizeof(low)); 61 memset(dfn,0, sizeof(dfn)); 62 memset(head,-1, sizeof(head)); 63 for(int i = 0; i<n; i++) 64 { 65 q[i].x = 1; 66 q[i].id = i; 67 } 68 q[0].x = 0; 69 70 tot = 0; 71 for(int i = 0; i<m; i++) 72 { 73 int u, v; 74 scanf("%d%d",&u,&v); 75 add(u,v); 76 add(v,u); 77 } 78 79 stamp = 0; 80 dfs(0,-1); 81 sort(q, q+n); 82 for(int i = 0; i<k; i++) 83 printf("%d %d\n",q[i].id, q[i].x); 84 putchar('\n'); 85 } 86 }