There are n
servers numbered from 0
to n-1
connected by undirected server-to-server connections
forming a network where connections[i] = [a, b]
represents a connection between servers a
and b
. Any server can reach any other server directly or indirectly through the network.
A critical connection is a connection that, if removed, will make some server unable to reach some other server.
Return all critical connections in the network in any order.
Example 1:
Input: n = 4, connections = [[0,1],[1,2],[2,0],[1,3]]
Output: [[1,3]]
Explanation: [[3,1]] is also accepted.
Constraints:
1 <= n <= 10^5
n-1 <= connections.length <= 10^5
connections[i][0] != connections[i][1]
开始没想到解法。后来看讨论区说用tarjan算法,这算法还没怎么看懂https://www.luogu.org/blog/styx-ferryman/chu-tan-tarjan-suan-fa-qiu-qiang-lian-tong-fen-liang-post。但其主要思路是要对每个遍历到的节点按遍历到的先后顺序 标号(为了表示处理先后顺序)。这样就能处理某节点的子孙节点连接到的最小标号节点,是不是小于此节点(其祖先)。而得知此节点是否在环中。以下解法dfs返回子孙节点往下连接到的最小序号。
class Solution {
List> ret;
ArrayList[] graph;
int[] index;
public List> criticalConnections(int n, List> connections) {
ret=new ArrayList<>();
graph=(ArrayList[])new ArrayList[n];
index=new int[n];
Arrays.fill(index,-1);
for(int i=0;i();
for(List con:connections){
int n1=con.get(0);
int n2=con.get(1);
graph[n1].add(n2);
graph[n2].add(n1);
}
dfs(0,-1,1);
return ret;
}
int dfs(int node,int pre,int deep){
if(index[node]!=-1){
return index[node];
}
index[node]=deep;
int r=100000000;
for(int n:graph[node]){
if(n!=pre&&index[n]index[node]){
List l=new ArrayList();
l.add(node);
l.add(n);
ret.add(l);
}
r=Math.min(r,v);
}
}
return r;
}
}
参考:https://www.cnblogs.com/yanyiming10243247/p/9294160.html
E. We Need More Bosses
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Your friend is developing a computer game. He has already decided how the game world should look like — it should consist of nnlocations connected by mm two-way passages. The passages are designed in such a way that it should be possible to get from any location to any other location.
Of course, some passages should be guarded by the monsters (if you just can go everywhere without any difficulties, then it's not fun, right?). Some crucial passages will be guarded by really fearsome monsters, requiring the hero to prepare for battle and designing his own tactics of defeating them (commonly these kinds of monsters are called bosses). And your friend wants you to help him place these bosses.
The game will start in location ss and end in location tt, but these locations are not chosen yet. After choosing these locations, your friend will place a boss in each passage such that it is impossible to get from ss to tt without using this passage. Your friend wants to place as much bosses as possible (because more challenges means more fun, right?), so he asks you to help him determine the maximum possible number of bosses, considering that any location can be chosen as ss or as tt.
Input
The first line contains two integers nn and mm (2≤n≤3⋅1052≤n≤3⋅105, n−1≤m≤3⋅105n−1≤m≤3⋅105) — the number of locations and passages, respectively.
Then mm lines follow, each containing two integers xx and yy (1≤x,y≤n1≤x,y≤n, x≠yx≠y) describing the endpoints of one of the passages.
It is guaranteed that there is no pair of locations directly connected by two or more passages, and that any location is reachable from any other location.
Output
Print one integer — the maximum number of bosses your friend can place, considering all possible choices for ss and tt.
Examples
input
Copy
5 5
1 2
2 3
3 1
4 1
5 2
output
Copy
2
input
Copy
4 3
1 2
4 3
3 2
output
Copy
3
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) {new Main().run();}
FastReader in = new FastReader();
PrintWriter out = new PrintWriter(System.out);
void run(){
work();
out.flush();
}
long mod=1000000007;
long gcd(long a,long b) {
return a==0?b:b>=a?gcd(b%a,a):gcd(b,a);
}
int n,m;
ArrayList[] graph;
int[] dp,dis;
int max=0;
void work() {
n=in.nextInt();
m=in.nextInt();
graph=(ArrayList[])new ArrayList[n];
for(int i=0;i();
}
dis=new int[n];
dp=new int[n];
Arrays.fill(dp, n);
for(int i=0;i=a) {
b=a;
a=v;
}else if(v>b) {
b=v;
}
}
}
max=Math.max(max,a+b);
//圈的起点代表整个圈,此时dp[node]==dis[node],如要得到强连通分量,这里弹出栈,还可以染色
if(dp[node]>=dis[node]) {
a++;
}
return a;
}
private void dfs1(int node, int cur ,boolean[] vis,int pre) {
vis[node]=true;
dis[node]=cur;
for(int nn:graph[node]) {
if(!vis[nn]) {
dfs1(nn,cur+1,vis,node);
dp[node]=Math.min(dp[node], dp[nn]);
}else if(nn!=pre){
dp[node]=Math.min(dp[node], dis[nn]);
}
}
}
}
class FastReader
{
BufferedReader br;
StringTokenizer st;
public FastReader()
{
br=new BufferedReader(new InputStreamReader(System.in));
}
public String next()
{
while(st==null || !st.hasMoreElements())//回车,空行情况
{
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
public int nextInt()
{
return Integer.parseInt(next());
}
public long nextLong()
{
return Long.parseLong(next());
}
}