首页 > 其他分享 >线性基与图论结合的经典问题

线性基与图论结合的经典问题

时间:2023-08-27 21:22:14浏览次数:32  
标签:基与 ll 路径 图论 异或 ans 线性 oplus dis

立体传送门:Luogu P4151

不急,一步一步来。

第一种情况,考虑我们现在已经有一条 \(1-> n\) 的路径,不妨设为 \(1->i->j->k->n\),异或起来为 \(dis_n\),那么我们的 \(ans\) 就是 \(dis_n\)。

第二种情况,在上种情况基础上,考虑这条路径上的 \(i\) 点有个环,不妨设这个环的异或起来为 \(I\),那么我们的 \(ans\) 就是 \(min(dis_n,dis_n\oplus I)\),即:走不走这个环。

第三种情况,在上种情况的基础上,考虑这条路径上的 \(j\) 有条到 \(a\) 的路径,然后 \(a\) 点上有个环,不妨设 \(j\) 连向 \(a\) 的路径异或起来是 $ J$,这个环异或起来为 \(A\),那么我们的 \(ans\) 就是 \(min(ans,ans\oplus J\oplus A\oplus J)\),即 \(min(ans,ans\oplus A)\),我们发现,这种情况跟第二种情况差不多,只需要知道整个环的异或值即可

第四种情况,在上种情况的基础上,考虑有条边为 \(k->i\),即有个环为 \(i->j->k->i\),不妨设该环的异或值为 \(K\),那我们的 \(ans\) 就是 \(min(ans,ans\oplus K)\),因为是无向边,所以从 \(i\) 到 \(k\) 的边有两条,为 \(i->j->k\) 和 \(i->k\) ,而\(ans\oplus K\) 就是走 \(i->k\) 这条。

我们发现:

1、对于第一种情况,我们只需要找到随便一条到达 \(n\) 的路径即可。对于第二到第四种情况,只要求出环的异或值即可。

2、上面四种情况包含了所有的图,只是数量更多罢了。

那么我们就可以根据发现的规律推做法:

对于发现 \(1\),我们可以用 \(dfs\) 找路径和环的异或值。

对于发现 \(2\),我们可以用线性基去做,求出在原来路径的基础上,走哪些环可以使异或值更大

上代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=250000;
ll n,m;
ll h[N],e[N],w[N],ne[N],idx;
void add(ll a,ll b,ll c)
{
	e[++idx]=b;
	w[idx]=c;
	ne[idx]=h[a];
	h[a]=idx;
}
ll dis[N],num[N];
bool vis[N];
void insert(ll x)
{
	for(ll i=63;i>=0;i--)
		if((1ll<<i)&x)
		{
			if(!num[i]) num[i]=x;
			x^=num[i];
		}
}
ll query(ll x)
{
	ll re=x;
	for(ll i=63;i>=0;i--)
		if((re^num[i])>re)
			re^=num[i];
	return re;
}
void dfs(ll wz,ll res)
{
	dis[wz]=res;
	vis[wz]=true;
	for(ll i=h[wz];i!=-1;i=ne[i])
		if(!vis[e[i]]) dfs(e[i],res^w[i]);
		else insert(res^w[i]^dis[e[i]]);
}
int main()
{
	memset(h,-1,sizeof h);
	scanf("%lld %lld",&n,&m);
	ll t1,t2,t3;
	for(ll i=1;i<=m;i++)
	{
		scanf("%lld %lld %lld",&t1,&t2,&t3);
		add(t1,t2,t3);
		add(t2,t1,t3);
	}
	dfs(1,0);
	printf("%lld\n",query(dis[n]));
	return 0;
}

最后,一个重要的细节,就是当数值是 \(long long\) 级别时,左移或右移的 \(1\) 是 \(1ll\)

标签:基与,ll,路径,图论,异或,ans,线性,oplus,dis
From: https://www.cnblogs.com/pengchujie/p/17660865.html

相关文章

  • 线性同余方程+中国剩余定理
    逆元求解\(ax=b\pmodm\),其实等价于\(ax+my=b\),然后扩欧就无了。可以应用于求当是\(a,p\)互质,求\(a\)在模\(p\)意义下的逆元,方法就是求解\(ax=1\pmodp\)。中国剩余定理(CRT)问题:有\(m_1,m_2,...,m_n\),\(n\)个整数两两互质,还给定\(a_1,a_2,...,a_n\),需要我们求解一个方程组:\(......
  • 图论基础
    图论基础树和图的存储无向图:没方向建图需要在两个节点间建两条相反的边add(a,b),add(b,a);有向图:有方向领接矩阵:g[a,b]=权重$a\tob$邻接表(常用):每个点上都有一个单链表,存储该点能到哪些点上去若有权重则加个w[N]数组,以idx为下标记录权值12,324,53NULL......
  • 「Note」图论方向 - 网络流
    1.网络流1.1.定义1.1.1.网络网络是指一个有向图\(G=(V,E)\),每条边\((u,v)\inE\)有一个权值,\(c(u,v)\)称为容量,当\((u,v)\notinE\)时,有\(c(u,v)=0\)。特殊地,在图中有源点、汇点两点,分别为\(s\inV,t\inV\)。1.1.2.流设流函数\(f(u,v)\to\R(u,v\inV)\)表示......
  • 用线性表实现的通讯录管理 C++代码
    /****************************************//*主控菜单处理测试程序main2.c************//***************************************/#include<iostream>#include<string>usingnamespacestd;#defineLIST_INIT_SIZE100#defineLISTINCREMENT10intOK=......
  • 线性回归基本原理和公式推导
    回复我们公众号“1号程序员”的“E001”可以获取《BAT机器学习面试1000题》下载链接。[关注并回复:【E001】]线性回归是一种监督式机器学习算法,它计算因变量与一个或多个独立特征之间的线性关系。当独立特征的数量为1时,被称为单变量线性回归;在存在多于一个特征的情况下,被称......
  • 线性筛不大全
    众所周知,OI界有一股清流,它的名字叫做筛法这之中,有一线性筛十分出名,人称XXS.今天稍微总结一下最近用过的,比较厉害的,线性筛.目前用到的比较常用的线性筛,大多是建立在质数的基础上的,也就是以最普通的筛法求质数为基点,向外延伸.筛法求质数voidWonder_of_U(){......
  • 《线性代数》2. 向量的高级话题
    规范化和单位向量在了解完向量的基础知识后,我们来探讨更多和向量有关的高级话题。首先向量是一个有向线段,由原点指向空间中的某一个点,所以向量除了具有方向之外,还应该具有大小。比如有两个向量\(\vec{u}\)、\(\vec{w}\),分别是\((3,4)^{T}\)、\((4,3)^{T}\),那么它们的长度是多......
  • 数据结构代码题-线性表
    王道数据结构大题代码线性表#include<stdio.h>#include<stdlib.h>voiddelMin(int*arr,intlen){ if(!len){ printf("数组为空"); return0; } intmin=*arr,minPos=0; for(inti=0;i<len;i++){ if(min>*(arr+i)){ min=*(arr+......
  • 《线性代数》1. 一切从向量开始
    什么是向量我们在初等数学的时候,研究的都是一个数,而到线性代数,我们将从研究一个数拓展到研究一组数,而一组数的基本表示方法就是向量(Vector)。向量是线性代数研究的基本元素,它就是一组数,比如\((1,2,3)\)就是一个向量。那么问题来了,向量究竟有什么作用呢?或者说我们研究一组数有......
  • 图论算法代码
    当参加数学建模竞赛时,图论算法是一个常用的解决方案之一。以下是一个使用Python实现的深度优先搜索(DFS)算法示例,用于遍历图的所有节点:点击查看代码classGraph:def__init__(self):self.adjacency_list={}defadd_edge(self,u,v):ifunot......