首页 > 其他分享 >Living-Dream 系列笔记 第87期

Living-Dream 系列笔记 第87期

时间:2024-12-06 17:10:31浏览次数:3  
标签:Living cur nxt int id dfn low Dream 87

点双连通分量

  • 定义:若在无向图 \(G\) 中,存在一个极大子图 \(G'\),使得 \(G'\) 中没有割点,则称 \(G'\) 为 \(G\) 的一个点双连通分量,记作 \(\texttt{V-DCC}\)。

  • 性质:一个点可能在多个 \(\texttt{V-DCC}\) 中,且这些点一定为割点。

  • 求取:我们使用类似强连通分量求取的方法,使用一个栈存储访问过的节点,每当找到一个「可能的割点」(即不一定两边都有联通块),就将它以及后边的节点记入同一个 \(\texttt{V-DCC}\),注意一下割点不能从栈中删除即可。

P8435

模板。

code
#include<bits/stdc++.h>
using namespace std;

const int N=2e6+5;
int n,m,rt,cnt,id;
int dfn[N],low[N];
vector<int> G[N],dcc[N];
stack<int> stk;

void tarjan(int cur){
	dfn[cur]=low[cur]=++cnt;
	stk.push(cur);
	if(cur==rt&&!G[cur].size()){
		dcc[++id].push_back(cur);
		return;
	}
	for(int i:G[cur]){
		if(!dfn[i]){
			tarjan(i);
			low[cur]=min(low[cur],low[i]);
			if(low[i]>=dfn[cur]){
				int now=0; ++id;
				while(!stk.empty()&&now!=i){
					now=stk.top();
					dcc[id].push_back(now);
					stk.pop();
				}
				dcc[id].push_back(cur);
			}
		}
		else
			low[cur]=min(low[cur],dfn[i]);
	}
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1,u,v;i<=m;i++){
		cin>>u>>v;
		if(u==v)
			continue;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			rt=i,tarjan(i);
	cout<<id<<'\n';
	for(int i=1;i<=id;i++){
		cout<<dcc[i].size()<<' ';
		for(int j:dcc[i])
			cout<<j<<' ';
		cout<<'\n';
	}
	return 0;
}

CF51F

诈骗题。

首先看到毛毛虫是一个树形结构,不难想到边双缩成一棵树(其实严格来说是一棵树加很多个自环,但是毛毛虫允许自环所以这不重要)。

考虑到毛毛虫需要一条主链,从贪心的角度考虑,选直径是最优的。

那么其他的点就必须操作吗?画图可以发现,叶子节点无需操作,因为它们可以在其他点合并的过程中带到主链的旁边去。注意这里的「叶子节点」是除去直径两端的叶子节点。

然后这题就没了。时间复杂度是 \(O(n+m)\) 的。

确实不难,个人认为最重要的是从毛毛虫本身的特点出发思考说需要用的算法,也即挖掘性质

code
//
//  绝世好(唐)题.cpp
//
//
//  Created by _XOFqwq on 2024/11/23.
//

#include <bits/stdc++.h>
using namespace std;

const int N=2e3+5,M=1e5+5;
int n,m;
int p,cnt,tot,id,dia;
int sumsiz,one,sumv;
int dfn[N],low[N];
int dcc[N],blk[N],siz[N],d[N];
bool ok[N][N];
bool bridge[M];
struct EDGE{
    int v,i;
};
vector<EDGE> G[N];
vector<int> V[N];

void tarjan(int cur,int edg){
    dfn[cur]=low[cur]=++cnt;
    for(auto nxt:G[cur]){
        if(!dfn[nxt.v]){
            tarjan(nxt.v,nxt.i);
            low[cur]=min(low[cur],low[nxt.v]);
            if(low[nxt.v]>dfn[cur])
                bridge[nxt.i]=1;
        }
        else if(nxt.i!=edg)
            low[cur]=min(low[cur],dfn[nxt.v]);
    }
}
void getdcc(int cur){
    dcc[cur]=id;
    siz[id]++;
    for(auto nxt:G[cur]){
        if(bridge[nxt.i]||dcc[nxt.v])
            continue;
        getdcc(nxt.v);
    }
}
void dfs(int cur){
    blk[cur]=tot;
    sumsiz+=siz[cur]-1;
    one+=(d[cur]==1);
    sumv++;
    for (int i:V[cur]) {
        if (!blk[i]) {
            dfs(i);
        }
    }
}
void getdia(int cur,int fa,int sum){
    if(sum>=dia){
        dia=sum;
        p=cur;
    }
    for(int i:V[cur]){
        if(i==fa)
            continue;
        getdia(i,cur,sum+1);
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m;
    for (int i=1,u,v; i<=m; i++) {
        cin>>u>>v;
        G[u].push_back({v,i});
        G[v].push_back({u,i});
    }
    for (int i=1; i<=n; i++) {
        if (!dfn[i]) {
            tarjan(i,0);
        }
    }
    for (int i=1; i<=n; i++) {
        if (!dcc[i]) {
            ++id,getdcc(i);
        }
    }
    for (int i=1; i<=n; i++) {
        for (auto nxt : G[i]) {
            if (dcc[i]!=dcc[nxt.v]&&!ok[dcc[i]][dcc[nxt.v]]) {
                V[dcc[i]].push_back(dcc[nxt.v]);
                V[dcc[nxt.v]].push_back(dcc[i]);
                d[dcc[i]]++;
                d[dcc[nxt.v]]++;
                ok[dcc[i]][dcc[nxt.v]]=ok[dcc[nxt.v]][dcc[i]]=1;
            }
        }
    }
    int ans=0;
    for (int i=1; i<=id; i++) {
        if (!blk[i]) {
            ++tot;
            sumsiz=one=p=sumv=0;
            dia=-1e9;
            dfs(i);
            getdia(i,0,1);
            getdia(p,0,1);
            ans+=sumsiz+sumv-(dia+one-(!one?0:2));
        }
    }
    ans+=tot-1;
    cout<<ans;
    return 0;
}

CF962F

tj

标签:Living,cur,nxt,int,id,dfn,low,Dream,87
From: https://www.cnblogs.com/XOF-0-0/p/18591153

相关文章

  • Mondriaan's Dream
    算法经典题,好好学一下首先用一条虚线把矩阵分为两部分,上面的部分已经填充完毕,下面还没有完成那么我们记录这条虚线(轮廓线)下方的\(n\)个方块,\(0\)表示没有填充砖块,\(1\)表示填充了砖块,那么如何转移呢?首先规定转移必须只能向上和向左填,这样可以简化,并......
  • [ABC287E] Karuta(字典树模板题 + 思维暴力两种做法)
    [ABC287E]Karuta题面翻译给定NNN个字符串Si......
  • 7-187 斐波那契数列
    任务描述:斐波那契数列是指这样的一个数列:1,1,2,3,5,8,13,21,...,这个数列从第3个数开始每个数都等于前两个数的和,请输出这个数列的前20项。输入格式:没有输入。输出格式:数据占域宽为8,每行输出5个数。输入样例:在这里给出一组输入。例如:输出样例:在这里给出相应的输出。例如:......
  • LOLBAS(Living Off the Land Binaries and Scripts)是指一种网络攻击技术,攻击者利用目标
    LOLBAS的英文全称是LivingOfftheLandBinariesandScripts。它指的是攻击者利用目标环境中已存在的合法二进制文件、脚本或工具来执行恶意活动的一系列技术和战术。这种方法通过使用操作系统或其软件中常见的工具和资源,避免了引入外部恶意软件或可疑的可执行文件,从而帮助攻......
  • springboot网络教学管理系统-计算机毕业设计源码40879
    目 录摘要1绪论1.1选题背景与意义1.2开发现状1.3论文结构与章节安排2 开发环境及相关技术介绍2.1MySQL数据库2.2 Tomcat服务器2.3 Java语言2.4 SpringBoot框架介绍3 网络教学管理系统系统分析3.1可行性分析3.1.1技术可行性分析3.1.2 ......
  • 洛谷P4387 【深基15.习9】验证栈序列(c嘎嘎)
    题目链接:P4387【深基15.习9】验证栈序列-洛谷|计算机科学教育新生态题目难度:普及/提高解题思路:首先这道题很明显是要用栈来解决的(题目都已经明示了),我们得利用好栈的后进先出的特点来模拟这道题,先读入入栈和出栈序列,然后将遍历入栈序列,边遍历边压入栈,然后与出栈序列比......
  • 力扣876. 链表的中间结点
    文章目录一、快慢指针二、运行代码链表的中间结点一、快慢指针我们学习快慢指针,是为了这种算法思想。顾名思义,是一个慢指针,一步一步走。快指针随心所欲,可以一次走两步,也可以一次走三步四步等。如果一次走两步的话,当快指针走到链表尾部的时候,慢指针恰好可以走到链......
  • Codeforces Round 987 (Div. 2)
    目录写在前面A签到B结论,枚举C构造,数学D枚举,数据结构Edfs,树形DP,构造写在最后写在前面比赛地址:https://codeforces.com/contest/2031退役?累了。妈的明天体测测完直接飞昆明感觉要爆了、、、A签到保证给定序列不升,要求修改到不降,则将所有元素修改至相等一定是不劣的。......
  • 《Django 5 By Example》阅读笔记:p383-p387
    《Django5ByExample》学习第14天,p383-p387总结,总计5页。一、技术总结1.asynchronoustask(异步任务)对于异步任务,书中使用的是celery和RabbitMQ,这也是平时工作中的主流用法。(1)celeryPython使用的celery包的名字也是celery。2.RabbitMQ(1)拉取镜像doc......
  • 洛谷题单指南-线段树-P3870 [TJOI2009] 开关
    原题链接:https://www.luogu.com.cn/problem/P3870题意解读:有n个数的序列,初始都是0,支持两种操作:将区间[l,r]内所有数异或1,求区间[l,r]内1个个数,输出所有求区间1的个数操作的结果。解题思路:灯的开关可以用0,1表示,改变灯的状态可以用异或操作,统计多少灯是开的就是计算1的个数,因此......