题意:求标号最小的最大割点.(删除该点后,指定点#sink能到达的点数减少最多).

析:由于不知道要去掉哪个结点,又因为只有100个结点,所以我们考虑用一个暴力,把所有的结点都去一次,然后用并查集去判断。

当然也可以用割点和桥的模板,最后再判断一下,哪个点后面的点有多少就好。

代码如下:

并查集+暴力:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e3 + 100;
const int mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
int x;
vector<P> v;
int p[105];
int Find(int x) { return x == p[x] ? x : p[x] = Find(p[x]); } int main(){
while(scanf("%d", &n) == 1 && n){
scanf("%d", &x);
scanf("%d", &m);
int u, vv;
v.clear();
for(int i = 0; i < m; ++i){
scanf("%d %d", &u, &vv);
v.push_back(P(u, vv));
}
int ans = 0, cnt = 0;
for(int i = 1; i <= n; ++i){
if(i == x) continue;
for(int j = 1; j <= n; ++j) p[j] = j;
for(int j = 0; j < v.size(); ++j){
u = v[j].first;
vv = v[j].second;
if(u == i || vv == i) continue;
int x = Find(u);
int y = Find(vv);
if(x != y) p[y] = x;
}
map<int, int> mp;
map<int, int> :: iterator it;
for(int j = 1; j <= n; ++j)
if(i != j) ++mp[Find(j)];
if(mp.size() <= 1) continue;
int y = Find(x);
if(cnt < n-mp[y]-1){
cnt = n-mp[y]-1;
ans = i;
}
} printf("%d\n", ans);
}
return 0;
}

割点和桥:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e2 + 5;
const int mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
vector<int> G[maxn];
bool cut[maxn];
int low[maxn], dfn[maxn], vis[maxn], ans[maxn]; void dfs(int cur, int fa, int d){
vis[cur] = 1;
dfn[cur] = low[cur] = d;
int u = 0;
for(int i = 0; i < G[cur].size(); ++i){
int v = G[cur][i];
if(v != fa && 1 == vis[v]){
if(dfn[v] < low[cur]) low[cur] = dfn[v];
}
if(!vis[v]){
dfs(v, cur, d+1);
++u;
if(low[v] < low[cur]) low[cur] = low[v];
if((fa == -1 && u > 1) || (fa != -1 && low[v] >= dfn[cur])) cut[cur] = true;
}
}
vis[cur] = 2;
} void dfs1(int u){
vis[u] = 1;
ans[u] = 1;
for(int i = 0; i < G[u].size(); ++i){
int v = G[u][i];
if(vis[v]) continue;
dfs1(v);
ans[u] += ans[v];
}
} int main(){
int rt;
while(scanf("%d", &n) == 1 && n){
scanf("%d", &rt);
scanf("%d", &m);
for(int i = 1; i <= n; ++i) G[i].clear();
int u, v;
for(int i = 0; i < m; ++i){
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(dfn, 0, sizeof dfn);
memset(cut, false, sizeof cut);
memset(low, 0, sizeof vis);
memset(vis, 0, sizeof vis);
dfs(rt, -1, 0);
memset(vis, 0, sizeof vis);
memset(ans, 0, sizeof ans);
dfs1(rt); int anss = 0, cnt = 0;
for(int i = 1; i <= n; ++i){
if(cut[i] && cnt < ans[i]){
cnt = ans[i];
anss = i;
}
}
printf("%d\n", anss);
}
return 0;
}

UVaLive 7456 Least Crucial Node (并查集+暴力 或者 求割点)的更多相关文章

  1. UVALive 7456 Least Crucial Node (并查集)

    Least Crucial Node 题目链接: http://acm.hust.edu.cn/vjudge/contest/127401#problem/C Description http://7 ...

  2. UVALive 7456 Least Crucial Node

    题目链接 题意: 给定一个无向图,一个汇集点,问哪一个点是最关键的,如果有多个关键点,输出序号最小的那个. 因为数据量比较小,所以暴力搜索就行,每去掉一个点,寻找和汇集点相连的还剩几个点,以此确定哪个 ...

  3. UVALive - 6910 (离线逆序并查集)

    题意:给处编号从1~n这n个节点的父节点,得到含有若干棵树的森林:然后再给出k个操作,分两种'C x'是将节点x与其父节点所连接的支剪短:'Q a b'是询问a和b是否在同一棵树中. 题解:一开始拿到 ...

  4. uvalive 4730王国kingdom(并查集+线段树)

     题意:有T组測试数据.每组数据的N表示有N个城市,接下来的N行里每行给出每一个城市的坐标(0<=x,y<=1000000),然后有M(1<M<200000)个操作,操作有 ...

  5. UVALive 6910 Cutting Tree(并查集应用)

    总体来说,这个题给的时间比较长,样例也是比较弱的,别的方法也能做出来. 我第一次使用的是不合并路径的并查集,几乎是一种暴力,花了600多MS,感觉还是不太好的,发现AC的人很多都在300MS之内的过得 ...

  6. POJ 1562 Oil Deposits (并查集 OR DFS求联通块)

    Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14628   Accepted: 7972 Des ...

  7. BZOJ 4668: 冷战 并查集&&暴力LCA(雾)

    利用并查集按秩合并,保存每个点合并的时间: 求时间时,就一直跳u=fa[u],并记录路径上时间的最大值,代表最后一次合并的时间 #include<cstdio> #include<i ...

  8. UVALive - 5031 Graph and Queries (并查集+平衡树/线段树)

    给定一个图,支持三种操作: 1.删除一条边 2.查询与x结点相连的第k大的结点 3.修改x结点的权值 解法:离线倒序操作,平衡树or线段树维护连通块中的所有结点信息,加个合并操作就行了. 感觉线段树要 ...

  9. fzu 2087并查集的运用求最小生成树的等效边

    //对数组排序后,对于边相同并且边的两端不在一个集合内的一定是等效边或者必加边, //第一数数,第二合并集合 #include<stdio.h> #include<stdlib.h& ...

随机推荐

  1. 校园网、教育网 如何纯粹访问 IPv6 网站避免收费

    我国校园网有可靠的 IPv6 网络环境,速度非常快.稳定,并且大多数高校在网络流量计费时不会限制 IPv6 的流量,也就是免费的.然而访问 IPv4 商业网络时,则会收费,并且连接的可靠性一般.可幸的 ...

  2. HTML5面试题-b

    感谢分享 面试有几点需要注意: 面试题目: 根据你的等级和职位变化,入门级到专家级:范围↑.深度↑.方向↑. 题目类型: 技术视野.项目细节.理论知识型题,算法题,开放性题,案例题. 进行追问: 可以 ...

  3. Objective-C面向对象-对象和类

    文章都是先由本人个人博客:孙占兴:www.teilim.com,先更新,随后CSDN博客才会更新,掌握第一动态请关注本人主站. 原文链接:http://www.teilim.com/objective ...

  4. DesiredSize,RenderSize&& Width ,ActualWidth

    做UI的时候刚入门,很多属性摸不着头脑,需要的功能和属性不能很快联系联想到,所以要慢慢积累UIElement 的DesiredSize 和 RenderSize UIElement 的DesiredS ...

  5. [LeetCode] 038. Count and Say (Easy) (C++/Python)

    索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 038. Cou ...

  6. 李洪强iOS开发之 - block的使用

     李洪强iOS开发之 - block的使用   01 - 定义block //支付block typedef void(^invokePayBlock)(CFBaseOrderModel *model ...

  7. HDU 6096 String 排序 + 线段树 + 扫描线

    String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...

  8. HDU 6113 度度熊的01世界 【DFS】(2017"百度之星"程序设计大赛 - 初赛(A))

    度度熊的01世界 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  9. java中创建对象的五种方法

    用最简单的描述来区分new关键字和newInstance()方法的区别:newInstance: 弱类型.低效率.只能调用无参构造.new: 强类型.相对高效.能调用任何public构造. newIn ...

  10. oracle中去掉文本中的换行符、回车符、制表符

    一.特殊符号ascii定义 制表符 chr(9)  换行符 chr(10) 回车符 chr(13) UPDATE tc_car_order set USE_REASON =  REPLACE('USE ...