HDU

# 题意

有一个简单图,n个点,m条边。对于每条割边,求出删去这条边后,在两个联通块中各取一个u,v。使得u<v,并且u尽量大而v尽量小。

# 思路

求出边双联通是肯定的。

答案的限制条件是重点。

假设分出来的两个联通块,一个的最大值是mx1,另一个的最大值是mx2。那么u = min(mx1, mx2),因为取个小点的,才能在另一个联通块中找到对应的v。

显然mx1,mx2中一个值等于n,所以我们只用找不包含n的联通块中的最大值。

怎么找,可以令n为根结点,dfs子树的最大值就行了。

又由于v越小越好,我们可以直接令v = u + 1;

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); } template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} const int inf = 0x3f3f3f3f; const int mod = 1e9+; /**********showtime************/
const int maxn = 1e5+;
vector<pii>mp[maxn];
set <pii>nmp[maxn];
int dfn[maxn],low[maxn],belong[maxn],tim;
int scc_cnt;
int ans[maxn];
int a[maxn], dp[maxn];
stack<int>st;
void dfs(int u, int fa) {
dfn[u] = low[u] = ++tim;
st.push(u);
for(pii p : mp[u]){
int v = p.fi;
if(v == fa) continue;
if(!dfn[v]) dfs(v, u);
if(!belong[v]) low[u] = min(low[u], low[v]);
}
if(low[u] == dfn[u]) {
scc_cnt++;
nmp[scc_cnt].clear();
int now;
while(true){
now = st.top(); st.pop();
belong[now] = scc_cnt;
a[scc_cnt] = max(a[scc_cnt], now);
if(now == u) break;
}
}
} void cal(int u, int fa) {
dp[u] = a[u];
for(pii p : nmp[u]) {
int v = p.fi, id = p.se;
if(v == fa) continue;
cal(v, u);
ans[id] = dp[v];
dp[u] = max(dp[u], dp[v]);
}
}
int main(){
int T; scanf("%d", &T);
while(T--) {
int n,m;
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++) mp[i].clear(), dfn[i] = ,dp[i] = , a[i] = ,belong[i] = ;
for(int i=; i<=m; i++) {
int u,v;
scanf("%d%d", &u, &v);
mp[u].pb(pii(v, i));
mp[v].pb(pii(u, i));
ans[i] = ;
}
tim = ;
scc_cnt = ;
for(int i=; i<=n; i++) if(!dfn[i]) dfs(i, i);
for(int u=; u<=n; u++) {
for(pii p : mp[u]) {
int v = p.fi;
if(belong[u] == belong[v]) continue;
nmp[belong[u]].insert(pii(belong[v], p.se));
}
}
cal(belong[n], belong[n]); for(int i=; i<=m; i++) printf("%d %d\n", ans[i], ans[i] + (ans[i] != ));
}
return ;
}

最新文章

  1. [转载] 构造linux 系统下免密码ssh登陆  _How to establish password-less login with SSH
  2. CWR Mobile简介
  3. android学习笔记13——ExpandableListView
  4. OpenCV4Android——No implementation found for native Lorg/opencv/core/Mat;.n_Mat ()J
  5. Android打开WIFI或者移动网络的代码实现
  6. C++面向对象设计
  7. hdu1151 Air Raid
  8. Android提供的系统服务之--TelephonyManager(电话管理器)
  9. GHOST备份
  10. js封装好的模仿qq消息弹窗代码
  11. 1067: spark.components:NavigatorContent 类型值的隐式强制指令的目标是非相关类型 String
  12. git第一篇---基本命令
  13. 教程,Python图片转字符堆叠图
  14. Android Toolbar 标题居中及字体样式自定义
  15. 存储过程中拼接sql并且参数化
  16. 20190320_head first pyhton学习笔记之构建发布
  17. centos 7添加硬盘及LVM扩容
  18. 再谈 apache设置virtualhost + apache的一些相关设值
  19. SQL注入之Sqli-labs系列第十九关(基于头部的Referer POST报错注入)
  20. cocos2dx渲染架构

热门文章

  1. 15. Java异常处理
  2. SpringBoot入门(二):日志及自定义属性
  3. 【Mac】nsurlsessiond 后台下载问题的解决方法
  4. 一道看似简单的go程序的深入分析
  5. 关于ajax异步请求的一个细节问题
  6. rgw main
  7. 封装 Gson 解析Json到对象是否失败
  8. Asp.NetCore源码学习[2-1]:配置[Configuration]
  9. 佳木斯集训Day4
  10. RBF神经网络