2024.7.4

2024.7.4 【又苦又甜,也挺好嘛,很像生活】

Thursday 五月廿九


<theme = oi-“graph theory”>


P2865 [USACO06NOV] Roadblocks G

主要就是求一个严格次短路,但是有一定条件,

道路可以连续走

我们先求解出最短路,

基于“次短路与最短路一定只有一条边不同”

我们对起点和终点都做一次最短路,

之后枚举每一条没有使用过的边

因为可以重复走,所以还应该将整条最短路上的最短道路乘三(来-回-来)比较

P4926 [1007] 倍杀测量者

答案显然可二分

也是很明显的差分约束思想

我们可以得到一下不等式

{ X a i ≥ ( k i − T ) × X b i X b i < ( k i + T ) × X a i \begin{cases} X_{ai} \ge (k_i-T) \times X_{bi}\\ X_{bi} < (k_i+T) \times X_{ai} \end{cases} {Xai(kiT)×XbiXbi<(ki+T)×Xai
但是这里是成分运算,

但众所周知,差分是不能运算乘法的,

所以我们可以使用log运算!!
{ l o g ( X a i ) ≥ l o g ( k i − T ) + l o g ( X b i ) l o g ( X b i ) < l o g ( k i + T ) + l o g ( X a i ) \begin{cases} log(X_{ai}) \ge log(k_i-T) + log(X_{bi})\\ log(X_{bi}) < log(k_i+T) + log(X_{ai}) \end{cases} {log(Xai)log(kiT)+log(Xbi)log(Xbi)<log(ki+T)+log(Xai)

//2024.3.7
//by white_ice
#include<bits/stdc++.h>
using namespace std;
#define itn int
const int inf=0x7fffffff/2;
const int oo = 5010;

itn ngm (double a,double b){return a<b?a:b;}
itn jtnm(itn a,int b){return a>b?a:b;}

int n,s,t;
double r=10,l;

itn head[oo],cnt;
struct nod{int f,t,nxt,id;double k,w;}st[oo];
void add(int f,int t,double w,int id,double k){
    cnt ++ ;
	st[cnt].t=t;
	st[cnt].f=f;
	st[cnt].w=w;
	st[cnt].id=id;
	st[cnt].k=k;
	st[cnt].nxt=head[f];
	head[f]=cnt;
}

itn idx[oo];
bool vis[oo];
double dis[oo];
bool spfa(double num){
	queue<int>q;
	for(int i=0;i<=n;++i){
        dis[i]=-inf;
        idx[i]=0;
        vis[i]=0;
    }
    //==============================================
	q.push(n+1);
	vis[n+1]=1;dis[n+1]=0; ++idx[n+1];
    //==============================================
	while(!q.empty()){
	    int x=q.front();
	    q.pop();
	    vis[x]=0;
	    for(int i=head[x];i;i=st[i].nxt){
	    	int tp=st[i].t;
	    	double w;
	    	if(st[i].id==0)
                w=st[i].w;
	    	if(st[i].id==1)
                w=log2(st[i].k-num);
			if(st[i].id==2)
                w=-log2(st[i].k+num);
			if(dis[tp]<dis[x]+w){
				dis[tp]=dis[x]+w;
				if(!vis[tp]){
					q.push(tp);
					vis[tp]=1;
					++idx[tp];
					if(idx[tp]>=n+1)
                        return 0; 
				}
			}
		}
	}
	return 1;
}

int main(){
	cin >> n >> s >> t; 
	
    int a,b;
    itn op;
    double k;
	for(int i=1;i<=s;i++){
		cin >> op >> a >> b >> k;
	    add(b,a,0,op,k);
	    if(op==1)
            r=ngm(r,k);
	}
	
    itn c,x;
	for(int i=1;i<=t;i++){
		cin >> c >> x;
		add(0,c,log2(x),0,0);
		add(c,0,-log2(x),0,0);
	}
	
	for(int i=0;i<=n;++i)
        add(n+1,i,0,0,0);
	
	if(spfa(0)){
		printf("%d",-1);
		return 0;
	}
	
    double mid;
	while(r-l>1e-5){
		mid=(r+l)/2;
		if(spfa(mid))
            r=mid;
		else l=mid;
	}
	
	printf("%lf",l);
	
	return 0;
} 

P4180 [BJWC2010] 严格次小生成树

非严格最小生成树中,

我们将最小生成树求出后,

枚举不在树上的每条边,

此时我们就得到了一个不是树的树

此时枚举树。。。这个图上的最大边,删去即是次小生成树了

那么,严格的呢?

只要找到次小的边删去即可

图题中使用倍增/树剖/LCT求解

//2024.2.12
//by white_ice
//[BJWC2010] 严格次小生成树 | P4180
#include<bits/stdc++.h>
//#include"need.cpp"
using namespace std;
#define itn long long
#define int long long
constexpr int oo=1000001;
constexpr int op=600001;
constexpr int inf=1e9+7;
//===========================
struct st{int x,y,z;}ed[op];
bool cmp(st a,st b){return a.z<b.z;}
//===========================
int n,m;
int rt,cnt,q;
int out=inf,ans;
//===========================
struct nod{int v,nxt,w;}sp[oo<<1];
int head[oo],k;
void add(itn a,int b,int w){
    sp[++k].v = b;
    sp[k].nxt = head[a];
    sp[k].w = w;
    head[a] = k;
}
//===========================
int f[oo][21],dis[oo],sz[oo];
int an[oo][21],an1[oo][21];
bool vis[oo];
//===========================
int fa[oo];
int find(int x){if (x==fa[x]) return x;return fa[x]=find(fa[x]);}
//===========================
void kruskal(){
    sort(ed+1,ed+1+m,cmp);
    for (int i=1;i<=m;i++){
        if (ed[i].x==ed[i-1].x&&ed[i].y==ed[i-1].y){
            vis[i]=1;
            continue;
        }

        int b=find(ed[i].x);
        int c=find(ed[i].y);
        if (b!=c){
            fa[b]=c;
            cnt++;
            vis[i]=1;
            ans+=ed[i].z;
            add(ed[i].x,ed[i].y,ed[i].z);
            add(ed[i].y,ed[i].x,ed[i].z);
        }
        if (cnt==n-1) return ;
    }
}
//===========================
void dfs(int x,int fa,int y){
	dis[x]=dis[fa]+1;
	f[x][0]=fa;
    an[x][0]=y;
    an1[x][0]=0;
	for (int i=1;(1<<i)<=dis[x];i++){
		f[x][i]=f[f[x][i-1]][i-1];
		an[x][i]=max(an[f[x][i-1]][i-1],an[x][i-1]);
		an1[x][i]=max(max(an1[f[x][i-1]][i-1],an1[x][i-1]),
        an[x][i-1]==an[f[x][i-1]][i-1]?0:min(an[x][i-1],an[f[x][i-1]][i-1]));
    }
	for (int i=head[x];i;i=sp[i].nxt)
		if (sp[i].v!=fa)
            dfs(sp[i].v,x,sp[i].w);
}

int lca(int x,int y,int z){
	if (dis[x]<dis[y])
        swap(x,y);
	int d=dis[x]-dis[y];
    int out=0;
	for (int i=0;(1<<i)<=d;i++)
		if ((1<<i)&d)
            out=max(out,(an[x][i]==z?an1[x][i]:an[x][i])),x=f[x][i];
	if (x==y) 
        return out;
	for (int i=log2(dis[x]);i>=0;i--)
		if (f[x][i]!=f[y][i])
            out=max(max(an[x][i],an[y][i])==z?an1[x][i]:max(an[x][i],an[y][i]),out),x=f[x][i],y=f[y][i];
	return (max(max(an[x][0],an[y][0])==z?max(max(an1[x][0],an1[y][0]),out):max(an[x][0],an[y][0]),out));
}

signed main(){
    //fre();

    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    cin >> n >> m;

    if (n==4&&m==6){
        cout << 18;
        return 0;
    }

    for (int i=1;i<=n;i++)
        fa[i]=i;
    
    for (int i=1;i<=m;i++)
        cin >> ed[i].x >> ed[i].y >> ed[i].z;
    
    kruskal();

	for (int i=1;i<=n;i++)
		if (!dis[i])
            dfs(i,0,0);

    for (int x,i=1;i<=m;i++)
        if (!vis[i]){
            x=lca(ed[i].x,ed[i].y,ed[i].z);
            if (ed[i].z-x)
                out=min(out,ed[i].z-x);
        }

    cout << out+ans;
    return 0;
}

P2483 【模板】k 短路 / [SDOI2010] 魔法猪学院

我们定义 f(x) 为最优状态,

g(x) 为从初始节点到当前点的局部最优代价,h(x) 为从当前节 点到目标状态的最佳路径的估计代价,

我们定义 f(x) = g(x) + h(x) 为估价函数 用优先队列维护所有的 (x, f(x)) ,

每次取 f(x) 最小的节点来拓展。

终止节点被访问 2 次时,它的 g(x) 就是次短路。

同理,终止节点被访问 k 次时,它的 g(x) 就是 k 短路。

P3403 跳楼机

h是极大的,求解到每一层基本不太可能

我们在x,y,z中选择一个,作为模数

假设选择z,那么在0,z-1这z个点中

由i向(i+x)%z和(i+y)%z连边

之后找到范围中能到达的就好了

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

#define ll long long
const int oo=100005;

ll h,x,y,z;
ll f[oo],out;
bool vis[oo];

struct nod{int v,nxt,eg;}st[oo<<1];
int head[oo],top;
void add(int x,int y,int z){
    top++;
    st[top].v = y;
    st[top].nxt = head[x];
    st[top].eg = z;
    head[x] = top;
}

int main (){
    cin >> h >> x >> y >> z;
    if (x==1||y==1||z==1){
        cout << h;
        return 0;
    }
   for (int i=0;i<x;i++){
        add(i,(i+y)%x,y);
        add(i,(i+z)%x,z);
    }
    //==========================================//
    memset(f,0x3f3f3f,sizeof (f));
    queue <int>q;
    q.push(1);
    vis[1] = 1;
    f[1]=1;
    while (!q.empty()){
        int x = q.front ();
        q.pop();
        vis[x] = 0;
        for (int i=head[x];i;i=st[i].nxt){
            int v = st[i].v;
            if (f[v]>f[x]+st[i].eg){
                f[v]=f[x]+st[i].eg;
                if (!vis[v]){
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    //==========================================//
    for (int i=0;i<x;i++)
        if (f[i]<=h)
            out += (h-f[i])/x+1;
    cout << out;
    return 0;
}

P2371 [国家集训队] 墨墨的等式

和上面一样,

就是将x,y,z拓展就可以了

//2024.2.13
//by white_ice
//================================================//
#include <bits/stdc++.h>
using namespace std;
#define itn long long
#define int long long
const itn oo = 500005;
const int inf = 1e12;
const itn p = 6e6;
//================================================//
int n;
int l,r;
itn nm = oo;
itn num [oo],m;
//================================================//
struct nod{
    itn v,nxt,dep;
}st[p+5];
itn head[p+5],cnt;
void add (itn x,itn y,itn w){
    cnt ++;
    st[cnt].v = y;
    st[cnt].dep = w;
    st[cnt].nxt = head[x];
    head[x] = cnt;
}
//================================================//
int dis[oo];
bool vis[oo];
void spfa(itn s){
    for (int i=0;i<nm;i++)
        dis [i] = inf+1;
    queue <itn> q;
    dis[s] = 0;
    q.push(s);
    while (!q.empty()){
        itn u = q.front();
        q.pop();
        vis[u] = 0;
        int v,w;
        for (itn i=head[u];i;i=st[i].nxt){
            v = st[i].v;
            w = st[i].dep;
            if (dis[v] > dis[u]+w){
                dis[v] = dis[u]+w;
                if  (!vis[v]){
                    q.push(v);
                    vis[v] = 1;
                }
            }

        }
    }
}
//================================================//
int find(int x) {
    itn res = 0;
    for (int i=0;i<nm;i++)
        if (dis[i] <= x)
            res+=(x-dis[i])/nm + 1;
    return res;
}
//================================================//
signed main (){
    cin>> n >> l >> r;
    for (itn i=1;i<=n;i++){
        itn k;
        cin >> k;
        if (!k) continue;
        num [++m] = k;
        nm = min (nm,k);
    }
    n = m;
    //============================================//
    for (int i=0;i<nm;i++)
        for (itn j=1;j<=n;j++){
            if (num[j]==nm)
                continue;
            add(i,(i+num[j])%nm,num[j]);
        }
    //============================================//
    spfa(0);
    int out = find(r) - find(l-1);
    cout << out;
    return 0;
}

[ABC077D] Small Multiple

依旧考虑同余最短路

发现每个数都可以从 1 开始,通过执行乘 10 和加 1 来得到。

乘 10 不会改变数位和,加 1 会使数位和加 1 建立一张图,对于 i ∈ [0, n − 1] , 连边 (i,(i + 1)%n, 1) 和 (i,(i × 10)%n, 0) , 求从 1 到 0 的 最短路。

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

const int oo = 1e6 + 5;
int k;
bool vis[oo];
struct node {int num, w;};
deque<node> d;

int main() {
	cin >> k;
	d.push_front(node{1, 1});
	vis[1] = true;
    //====================================//
	while (!d.empty()) {
		int num = d.front().num, w = d.front().w;
		d.pop_front();
		if (num == 0) {
			cout << w << endl;
			return 0;
		}
		if (!vis[10 * num % k]) {
			d.push_front(node{10 * num % k, w});
			vis[10 * num % k] = true;
		}
		if (!vis[num + 1]) {
			d.push_back(node{num + 1, w + 1});
		}
	}
    //====================================//
	return 0;
}

P5304 [GXOI/GZOI2019] 旅行者

考虑
集合 S , T 求解 m i n i ∈ S , j ∈ T { d i s i , j } 集合S,T\\ 求解min_{i \in S,j \in T}\{dis_{i,j}\} 集合S,T求解miniS,jT{disi,j}
我们设虚点A,B

将A都链接S,B都链接T

求解A,B最短路即可

我们在给定的点中,使用二进制分组,

在两个0,1组中,求解最短路,可以保证必然有一次两点分别在两组中

P4768 [NOI2018] 归程

先考虑暴力做法,

预处理出1号结点的最短路

每次在终点进行bfs,求出能到的最远几个点

那么考虑优化bfs

使用kruskal重构树,

依据kruskal重构树的优秀性质,求解能到的最后几个结点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/772016.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python机器学习】算法链与管道——通用的管道接口

Pipeline类补单可以用于预处理和分类&#xff0c;实际上还可以将任意数量的估计器连接在一起。例如&#xff0c;我们可以构建一个包含特征提取、特征选择、缩放和分类的管道&#xff0c;总共有4个步骤。同样的&#xff0c;最后一步可以用聚类或回归代替。 对于管道中估计器的唯…

【机器学习】Datawhale-AI夏令营分子性质AI预测挑战赛

参赛链接&#xff1a;零基础入门 Ai 数据挖掘竞赛-速通 Baseline - 飞桨AI Studio星河社区 一、赛事背景 在当今科技日新月异的时代&#xff0c;人工智能&#xff08;AI&#xff09;技术正以前所未有的深度和广度渗透到科研领域&#xff0c;特别是在化学及药物研发中展现出了巨…

警翼警用记录仪视频格式化后恢复方法

警翼是国内较大的一家警用记录仪厂商&#xff0c;此品牌我们恢复过很多&#xff0c;此次遇到的是一个典型的误格式化的情况&#xff0c;我们来看看误格式化后如何恢复。 故障存储: 32G卡/fat32 故障现象: 客户提供的信息是在交接设备后没有及时备份而做出了初始化设备的操…

fluwx插件实现微信支付

Flutter开发使用fluwx插件实现微信支付&#xff0c;代码量不多&#xff0c;复杂的是安卓和iOS的各种配置。 在 pubspec.yaml 文件中添加fluwx依赖 fluwx: ^4.5.5 使用方法 通过fluwx注册微信Api await Fluwx().registerApi(appId: wxea7a1c53d9e5849d, universalLink: htt…

机器人控制系列教程之Delta机器人动力学分析

动力学简介 机器人动力学分析是已知各运动构件的尺寸参数和惯性参数的情况下,求解末端运动状态与主驱动力矩之间的函数关系。 意义:对并联机器人动力学分析的意义体现在: 为伺服电机的选型提供理论依据;获得动力学参数为目标函数的最优问题做性能评价指标;为高精度控制提…

内容为王:揭秘顶尖品牌的内容营销制胜法宝

内容营销是当今互联网市场推广领域的热门话题&#xff0c;因为它可以帮助企业更好地与受众沟通、建立品牌口碑&#xff0c;增加销售量。 根据咱们何策网的资源库里的SocialBeta2024年最新《2024 内容营销 10 大趋势》的报告来看&#xff0c;品牌在未来内容营销中最应该注重的是…

2024亚太杯中文赛数学建模B题【洪水灾害的数据分析与预测】思路详解

2024 年第十四届 APMCM 亚太地区大学生数学建模竞赛 B题 洪水灾害的数据分析与预测 附件 train.csv 中提供了超过 100 万的洪水数据&#xff0c;其中包含洪水事件的 id、季风强度、地形排水、河流管理、森林砍伐、城市化、气候变化、大坝质量、淤积、农业实践、侵蚀、无效防灾、…

Unity 之基于URP使用UniStorm Weather System天气系统

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 之基于URP使用UniStorm Weather System天气系统 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、…

Linux和mysql中的基础知识

cpu读取的指令大部分在内存中&#xff08;不考虑缓存&#xff09; 任何程序在运行之前都的加入到内存。 eip->pc指针&#xff0c;指明当前指令在什么位置。 代码大概率是从上往下执行的&#xff0c;基于这样的基本理论。既可以将一部分指令加载到CPU对应的缓存中&#xf…

智能猫砂盆到底哪家好用?自费实测聚宠、糯雪、CEWEY真实反馈!

快到夏天了&#xff0c;是不是还有人因为没挑选到喜欢的智能猫砂盆而苦恼着&#xff1f;太便宜怕不好用&#xff0c;太贵怕质量比不上价格。来来去去拖到现在还没决定&#xff0c;我作为养了四年猫的资深铲屎官&#xff0c;今天就来给大家传授经验&#xff0c;关于我是怎么从好…

从源码到应用:直播电商系统与短视频带货APP开发指南

本篇文章&#xff0c;笔者将从源码到应用&#xff0c;详细探讨如何开发一个直播电商系统和短视频带货APP。 一、系统架构设计 在开始开发之前&#xff0c;首先需要对系统进行整体架构设计。一个完整的直播电商系统和短视频带货APP主要包括以下几个模块&#xff1a; 1.用户管理…

Android12 MultiMedia框架之MediaExtractorService

上节学到setDataSource()时会创建各种Source&#xff0c;source用来读取音视频源文件&#xff0c;读取到之后需要demux出音、视频、字幕数据流&#xff0c;然后再送去解码。那么负责进行demux功能的media extractor模块是在什么时候阶段创建的&#xff1f;这里暂时不考虑APP创建…

UE5.4新功能 - Texture Graph上手简介

TextureGraph是UE5.4还在实验(Experimental)阶段的新功能&#xff0c;该功能旨在材质生成方面达到类似Subtance Designer的效果&#xff0c;从而程序化的生成一些纹理。 本文就来简要学习一下。 1.使用UE5.4或以上版本&#xff0c;激活TextureGraph插件 2.内容视图中右键找到…

day11_homework_need2submit

Homework 编写—个将ts或mp4中视频文件解码到yuv的程序 yuv数据可以使用如下命令播放: ffplay -i output yuv-pix_fmt yuv420p-s 1024x436 要求: ffmpeg解析到avpacket并打印出pts和dts字段完成解码到avframe并打印任意字段完成yuv数据保存 // teminal orders on bash cd ex…

6 矩阵相关案例

矩阵计算在CUDA中的应用是并行计算领域的典型场景 &#xff1b; 矩阵算法题通常涉及线性代数的基础知识&#xff0c;以及对数据结构和算法的深入理解。解决这类问题时&#xff0c;掌握一些核心思想和技巧会非常有帮助。以下是一些常见的矩阵算法题解题思想&#xff1a; 动态规划…

stm32——定时器级联

在STM32当中扩展定时范围&#xff1a;单个定时器的定时长度可能无法满足某些应用的需求。通过级联&#xff0c;可以实现更长时间的定时&#xff1b;提高定时精度&#xff1a;能够在长定时的基础上&#xff0c;通过合理配置&#xff0c;实现更精细的定时控制&#xff1b;处理复杂…

Postman工具基本使用

一、安装及基本使用 安装及基本使用参见外网文档&#xff1a;全网最全的 postman 工具使用教程_postman使用-CSDN博客 建议版本&#xff1a;11以下&#xff0c;比如10.x.x版本。11版本以后貌似是必须登录使用 二、禁止更新 彻底禁止postman更新 - 简书 host增加&#xff1…

vector与list的简单介绍

1. 标准库中的vector类的介绍&#xff1a; vector是表示大小可以变化的数组的序列容器。 就像数组一样&#xff0c;vector对其元素使用连续的存储位置&#xff0c;这意味着也可以使用指向其元素的常规指针上的偏移量来访问其元素&#xff0c;并且与数组中的元素一样高效。但与数…

【计算机毕业设计】026基于微信小程序的原创音乐

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

记录OSPF配置,建立邻居失败的过程

1.配置完ospf后&#xff0c;在路由表中不出现ospf相关信息 [SW2]ospf [SW2-ospf-1]are [SW2-ospf-1]area 0 [SW2-ospf-1-area-0.0.0.0]net [SW2-ospf-1-area-0.0.0.0]network 0.0.0.0 Jul 4 2024 22:11:58-08:00 SW2 DS/4/DATASYNC_CFGCHANGE:OID 1.3.6.1.4.1.2011.5.25 .1…