The Suspects(并查集)

Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology,
 was recognized as a global threat in mid-March 2003. To minimize transmission to others,
the best strategy is to separate the suspects from others.
In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups.
Students in the same group intercommunicate with each other frequently, and a student
may join several groups. To prevent the possible transmissions of SARS, the NSYSU
collects the member lists of all student groups, and makes the following rule in their
standard operation procedure (SOP).
Once a member in a group is a suspect, all members in the group are suspects.
However, they find that it is not easy to identify all the suspects when a student
is recognized as a suspect. Your job is to write a program which finds all the suspects.
Input
The input file contains several cases. Each test case begins with two integers n and m in a line,
 where n is the number of students, and m is the number of groups.
You may assume that 0 < n <= 30000 and 0 <= m <= 500. Every student is numbered
by a unique integer between 0 and n−1, and initially student 0 is recognized as
 a suspect in all the cases. This line is followed by m member lists of the groups,
 one line per group. Each line begins with an integer k by itself representing the
number of members in the group. Following the number of members, there are
k integers representing the students in this group. All the integers in a line are
 separated by at least one space.
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.
Output
For each case, output the number of suspects in one line.
Sample Input
100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0
Sample Output
4
1
1
题意:有一个学校,有N个学生,编号为0-N-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,
并且这些人如果还参加了别的社团,他所在的社团照样全部感染,求感染的人数。
分析:分社团将学生加入并查集,最后找根结点为0的元素个数。
#include<stdio.h>
int pre[300005];
int find(int x)
{
    return pre[x]==x?x:pre[x]=find(pre[x]);//找父结点并压缩路径。
}
void Merge(int a,int b) //加入并查集。
{
    int f1=find(a);
    int f2=find(b);
    
    if(f1==0)//保证根结点一定是0
        pre[f2]=f1;
    
    else if(f2==0)
        pre[f1]=f2;

    else
        pre[f1]=f2;
}
int main()
{
    int n,m,mem[30005];
    int k,i,j;
    while(scanf("%d%d",&n,&m) && (n+m))
    {
        for(i=0;i<=n;i++)
            pre[i]=i;

        for(i=0;i<m;i++)
        {
            scanf("%d",&k);

            for(j=0;j<k;j++)
                scanf("%d",&mem[j]);

            for(j=1;j<k;j++)
                Merge(mem[0],mem[j]); //加入并查集中。

        }

        int ans=0;

        for(i=0;i<n;i++)
            if(0==find(i)) //找根结点为0的集合。
                ans++;

        printf("%d\n",ans);
    }
    return 0;
}



<think>我们讨论的是在Windows环境下如何获取Java虚拟机(JVM)的快照(通常指的是堆转储,heapdump)并进行分析。堆转储是Java进程在某个时间点的内存快照,主要用于分析内存泄漏、内存使用情况等问题。###获取堆转储(HeapDump)的方法####1.使用jmap工具(命令行方式)jmap是JDK自带的一个命令行工具,可以生成堆转储文件。命令格式:```bashjmap-dump:format=b,file=<filename.hprof><pid>```其中:-`<filename.hprof>`:生成的堆转储文件名,通常以.hprof为后缀。-`<pid>`:目标Java进程的进程ID。如何获取进程ID?可以使用`jps`命令(也是JDK自带)来查看当前运行的Java进程及其进程ID。示例:```bashjps-l```输出会显示所有Java进程的pid和主类名。然后使用jmap:```bashjmap-dump:format=b,file=dump.hprof1234#假设进程ID为1234```####2.使用JVM参数触发堆转储可以在启动JVM时添加参数,使得在发生OutOfMemoryError时自动生成堆转储文件。参数:```bash-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=<path>```例如:```bashjava-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=C:\dumps\myapp.hprof-jarmyapp.jar```这样当程序抛出OutOfMemoryError时,会自动在指定路径生成堆转储文件。####3.使用jvisualvm工具(图形化工具)jvisualvm也是JDK自带的一个图形化监控工具,可以生成堆转储。步骤:1.打开jvisualvm(在JDK的bin目录下,双击jvisualvm.exe)。2.在左侧应用程序树中,找到目标Java进程。3.右键点击该进程,选择“堆转储”选项。4.堆转储生成后,会显示在应用程序树中,可以右键另存为文件。####4.使用jcmd工具(命令行方式)jcmd也是JDK自带的工具,功能强大,可以生成堆转储。命令格式:```bashjcmd<pid>GC.heap_dump<filename.hprof>```示例:```bashjcmd1234GC.heap_dumpC:\dumps\dump.hprof```###分析堆转储文件生成堆转储文件后,可以使用以下工具进行分析:####1.使用jhat工具(命令行)jhat是JDK自带的堆转储分析工具,启动一个HTTP服务器,可以在浏览器中查看分析结果。命令:```bashjhatdump.hprof```默认端口为7000,访问http://localhost:7000即可。注意:jhat在分析大堆转储时可能会比较慢,且功能相对简单。####2.使用jvisualvmjvisualvm也可以分析堆转储文件。打开jvisualvm,然后选择“文件”->“装入”,选择堆转储文件(.hprof)。可以查看类实例数量、内存占用、对象引用关系等。####3.使用EclipseMemoryAnalyzer(MAT)MAT是一个功能强大的堆转储分析工具,可以检测内存泄漏、分析内存消耗等。下载地址:https://www.eclipse.org/mat/downloads.php使用步骤:1.下载并解压MAT。2.启动MAT(MemoryAnalyzer.exe),然后打开堆转储文件。3.MAT会生成分析报告,包括内存泄漏嫌疑点、大对象等。####4.使用IntelliJIDEAIntelliJIDEA内置了堆转储分析功能(专业版)。打开方式:File->Open,选择堆转储文件。可以查看对象实例、引用链等。###示例:使用jmap生成堆转储并分析假设我们有一个Java应用,进程ID为1234。步骤1:生成堆转储```bashjmap-dump:format=b,file=C:\dumps\myapp_dump.hprof1234```步骤2:使用MAT打开`myapp_dump.hprof`文件进行分析。###注意事项-生成堆转储时,JVM会暂停(Stop-The-World),因此生产环境中要谨慎操作,避免在高峰期进行。-堆转储文件可能很大,确保有足够的磁盘空间。###相关问题§§相关问题§§:1.在Windows环境下,除了jmap,还有哪些命令行工具可以生成Java堆转储?2.如何配置JVM参数以便在发生OutOfMemoryError时自动生成堆转储文件?3.使用EclipseMAT分析堆转储时,如何识别内存泄漏?4.在生成堆转储时,为什么会出现“无法连接进程”的错误?如何解决?</think>### 如何 dump Java 虚拟机快照并分析(Windows 环境) #### 1. **生成堆转储(Heap Dump)的方法** **方法一:使用 jmap 工具(命令行)** ```bash jmap -dump:format=b,file=dump.hprof <pid> ``` - **说明**: - `<pid>` 是目标 Java 进程的 ID(通过 `jps -l` 获取) - `dump.hprof` 是生成的堆转储文件名 - **示例**: ```bash jps -l # 查看进程 ID(如 12345) jmap -dump:format=b,file=C:\dumps\myapp_dump.hprof 12345 ``` **方法二:JVM 启动参数(自动触发 OOM 时 dump)** ```java java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\dumps\myapp_oom.hprof -jar MyApp.jar ``` - **说明**:当发生 `OutOfMemoryError` 时自动生成 dump。 **方法三:使用 jcmd(JDK 7+ 推荐)** ```bash jcmd <pid> GC.heap_dump C:\dumps\dump.hprof ``` **方法四:通过 VisualVM(图形化工具)** 1. 启动 `jvisualvm.exe`(位于 `JDK/bin` 目录) 2. 右键目标进程 → 选择 **堆 Dump** --- #### 2. **分析堆转储的工具** **工具一:Eclipse Memory Analyzer (MAT)** 1. 下载地址:[https://www.eclipse.org/mat/](https://www.eclipse.org/mat/) 2. 分析步骤: - 打开 MAT → 选择 **File → Open Heap Dump** - 查看关键报告: - **Leak Suspects Report**(内存泄漏嫌疑对象) - **Histogram**(对象数量排序) - **Dominator Tree**(内存占用支配树) **工具二:VisualVM 分析** - 打开 VisualVM → **File → Load** → 选择 `.hprof` 文件 - 查看 **Classes**(类内存占用)和 **Instances**(实例详情) **工具三:命令行分析(jhat)** ```bash jhat -J-Xmx4G C:\dumps\dump.hprof ``` - 访问 `http://localhost:7000` 查看分析结果(适合小型 dump) --- #### 3. **代码示例:触发 OOM 并自动生成 Dump** ```java public class OOMTrigger { public static void main(String[] args) { // JVM 参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\dumps List<byte[]> leakList = new ArrayList<>(); while (true) { leakList.add(new byte[1024 * 1024]); // 持续分配 1MB 内存 } } } ``` - **运行结果**: - 触发 OOM 后在 `C:\dumps` 生成 `java_pid<pid>.hprof` 文件。 --- #### 4. **分析实战:MAT 定位内存泄漏** 1. 打开 `myapp_oom.hprof` 文件 2. 查看 **Leak Suspects** 报告: - 报告会提示 `Problem Suspect 1: 占用 98% 内存的 byte[] 对象` 3. 点击 **Details** → 查看 **Accumulated Objects** 找到持有对象的 GC Root: - 通常为静态集合类(如 `static Map`)未释放引用。 --- ### 注意事项 1. **权限问题**:确保 dump 输出目录有写入权限。 2. **磁盘空间**:dump 文件大小可能接近 JVM 堆最大值。 3. **生产环境**:建议在低峰期执行 `jmap`,避免 STW 暂停。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值