1 条题解

  • 0
    @ 2025-8-24 22:41:08

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar FHenryh
    §『支持互关』§

    搬运于2025-08-24 22:41:08,当前版本为作者最后更新于2023-05-06 21:49:51,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目概述

    题目传送门

    在一棵树中新增一条边,使得这个图产生一个环,求在环上的点。

    思路:

    对于这道题我的思路类似于拓补排序

    首先可以将无向图转化为有向图,即将对于每条无向边变换为双向建边,就好处理了。

    在这种情况下,很显然当一个点的入度大于或等于 22 时,即有不止一条边连向这个点时,该点就在环上。

    我们可以建一个布尔类型 visvis 数组来标记这个点的入度是否等于 11,那么这个点就不在环上,那么没有被标记的点就是我们要求的答案了。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+1; 
    int n;
    int in[N];
    vector<int>e[N];
    bool vis[N];//标记入度是否为1,即该点是否在环上
    void topo()//拓补排序
    {
    	queue<int>q;
    	for(int i=1;i<=n;i++)
    		if(in[i]==1)//标记入度为1的点
    		{
    			q.push(i);
    			vis[i]=true;
    		}
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=0;i<e[u].size();i++)
    		{
    			int v=e[u][i];
    			in[v]--;
    			if(in[v]==1)//标记入度为1的点
    			{
    				q.push(v);
    				vis[v]=true;
    			}
    		}
    	}
    }
    void print()//输出未标记的点
    {
    	for(int i=1;i<=n;i++)
    		if(!vis[i])cout<<i<<' ';
    }
    int main()
    {
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		int u,v;
    		cin>>u>>v;
    		e[u].push_back(v);
    		e[v].push_back(u);//双向建边
    		in[u]++;
    		in[v]++;//两点的入度都增加
    	}
    	topo();
    	print();
    	return 0;
    }
    
    • 1

    信息

    ID
    5965
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者