[codeforces] 1000 E. We Need More Bosses
题目链接:
题目大意:
给一个 n(2≤n≤3∗105) n ( 2 ≤ n ≤ 3 ∗ 10 5 ) 个点, m(n−1≤m≤3∗105) m ( n − 1 ≤ m ≤ 3 ∗ 10 5 ) 条边的无向图, 对于任意的两个点, 最多有多少条特殊边, 特殊边就是去掉这条边这两个点就无法互达.
可以理解为对于任意的两个点有多少条只是这两个点的割边.
思路:
首先求出割边, 然后割边的边权设为1, 其他的边权设为0, 跑一个最长链即可.
代码:
/********************************************
*Author* :ZZZZone
*Created Time* : 五 7/ 6 15:43:52 2018
* Ended Time* : 五 7/ 6 23:16:45 2018
*********************************************/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;
inline void OPEN(string s){
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
}
const int MAXN = 3e5;
vector<PII> edge[MAXN+5];
vector<PII> nedge[MAXN+5];
bool is_cut_p[MAXN+5], is_cut_edge[MAXN+5], vis[MAXN+5];
int pre[MAXN+5], low[MAXN+5];
int fa[MAXN+5];
int n, m, dfs_clock;
int maxlen[MAXN+5];
int find(int x){
if(fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}
int Dfs(int u, int fa){
int lowu = pre[u] = ++dfs_clock;
for(int i = 0; i < edge[u].size(); i++){
int v = edge[u][i].first;
int id = edge[u][i].second;
if(pre[v] == 0){
int lowv = Dfs(v, u);
lowu = min(lowu, lowv);
if(lowv >= pre[u]){
is_cut_p[u] = true;
if(lowv > pre[u]){
is_cut_edge[id] = true;
}
}
}
else if(pre[v] < pre[u] && v != fa){
lowu = min(lowu, pre[v]);
}
}
low[u] = lowu;
return lowu;
}
void Init(){
scanf("%d %d", &n, &m);
for(int i = 1; i <= m; i++){
int u, v;
scanf("%d %d", &u, &v);
edge[u].push_back(PII(v, i));
edge[v].push_back(PII(u, i));
}
for(int i = 1; i <= n; i++){
fa[i] = i;
}
Dfs(1, -1);
for(int u = 1; u <= n; u++){
for(int j = 0; j < edge[u].size(); j++){
int v = edge[u][j].first;
if(find(u) != find(v)){
fa[find(u)] = find(v);
nedge[u].push_back(edge[u][j]);
}
}
}
}
void Solve(){
queue<int> que;
memset(vis, false, sizeof(vis));
vis[1] = true;
que.push(1);
while(!que.empty()){
int now = que.front(); que.pop();
for(int i = 0; i < edge[now].size(); i++){
int v = edge[now][i].first;
if(vis[v]) continue;
int id = edge[now][i].second;
maxlen[v] = maxlen[now];
if(is_cut_edge[id]) maxlen[v]++;
vis[v] = true;
que.push(v);
}
}
//for(int i = 1; i <= n; i++) printf("%d ", maxlen[i]);
int tmp = 1;
for(int i = 1; i <= n; i++) {
if(maxlen[i] > maxlen[tmp]) tmp = i;
}
memset(vis, false, sizeof(vis));
memset(maxlen, 0, sizeof(maxlen));
vis[tmp] = true;
que.push(tmp);
while(!que.empty()){
int now = que.front(); que.pop();
for(int i = 0; i < edge[now].size(); i++){
int v = edge[now][i].first;
if(vis[v]) continue;
int id = edge[now][i].second;
maxlen[v] = maxlen[now];
if(is_cut_edge[id]) maxlen[v]++;
vis[v] = true;
que.push(v);
}
}
//for(int i = 1; i <= n; i++) printf("%d ", maxlen[i]);
}
int main()
{
Init();
Solve();
int ans = 0;
for(int i = 1; i <= n; i++) ans = max(ans, maxlen[i]);
printf("%d\n", ans);
return 0;
}