题意:求标号最小的最大割点.(删除该点后,指定点#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. OD调试器调试Delphi程序按钮事件断点方法

    这几天我调试一个Delphi程序,总是无法断点按钮事件,像我这样的菜鸟断点按钮事件真心累啊.所以我分享一下我下断点的经验!希望新手们少走弯路!!   工具/原料   OD调试器 Delphi程序 方法 ...

  2. 使网页适应UIWebView的宽度

    比較简单的做法是:在- (void)webViewDidFinishLoad:这种方法中,改动JavaScript的值: //UIWebViewDelegate - (void)webViewDidF ...

  3. thinkphp getField( )和field( )

    thinkphp getField( )和field( )   做数据库查询的时候,比较经常用到这两个,总是查手册,记不住,现在把它总结下,希望以后用的时候不查手册了. 不管是用select 查询数据 ...

  4. poj 1015 Jury Compromise(背包+方案输出)

    \(Jury Compromise\) \(solution:\) 这道题很有意思,它的状态设得很...奇怪.但是它的数据范围实在是太暴露了.虽然当时还是想了好久好久,出题人设了几个限制(首先要两个的 ...

  5. ALVtree 显示BOM结构

      REPORT  z_barry_alv_tree1_bom MESSAGE-ID oo. TABLES: stpox.INCLUDE <icon>. CLASS: cl_gui_col ...

  6. 有关 安装MySQL的错误

    1.登录SQLyog 密码与MySQL设置不一致. 2.上一次安装MySQL没有卸载干净,(排查删除: (1)搜索C盘删除相关文件(隐藏目录   C:\ProgramData  下寻找 mysql ) ...

  7. i MySQL 查看约束,添加约束,删除约束

    查看表的字段信息:desc 表名; 查看表的所有信息:show create table 表名; 添加主键约束:alter table 表名 add constraint 主键 (形如:PK_表名) ...

  8. Flume 和 kafka的区别和对比

    定义: Flume:是Cloudera提供的一个分布式的海量日志采集.聚合和传输的系统: Kafka:是一种高吞吐量的分布式发布订阅消息系统: 各特点: 场景: Flume主要是和HDFS\HBase ...

  9. 织梦CMS被挂马特征汇总

    一.织梦CMS被挂马特征汇总 2013织梦CMS被挂马特征汇总.最近很多朋友反应后台多了几个系统管理员用户:service.spider等,而且自己之前的管理员用户登陆时候会提示用户名不存在.还有朋友 ...

  10. html5--6-60 阶段练习7-下拉菜单

    html5--6-60 阶段练习7-下拉菜单 学习要点 综合运用所学过的知识完成一个下拉菜单的小练习,加深对学过知识点的综合应用能力. <!DOCTYPE html> <html l ...