Processing math: 5%

线性基【CF845G】Shortest Path Problem?

Description

给定一张 n 个点 m 条边的无向图,一开始你在点 1,且价值为 0

每次你可以选择一个相邻的点,然后走过去,并将价值异或上该边权

如果在点 n,你可以选择结束游戏

求一种方案,使得结束游戏后价值最小

n,m \le 10^5

Input

第一行为两个整数n,m代表有n个点m条边。

接下来m行,描述一条从xy长度为z的无向边。

Output

一个整数,代表最小价值。

首先,很明确的一点,题目要求我们求出很多条边的最小异或和。

由此,我们可以想到线性基

由于我们可以重复经过一些边,那么根据异或性质,当这条边被重复走过两次,那它对答案的贡献就是0。但是即使这样,它还可能连向其他的点。

虽然我们没办法枚举边,但是可以考虑将这些边所在分为两种。

  1. 环上的边
  2. 链上的边

但是我们通向一个环的时候会经过一条连向这个环的边两次。(一进一出)。

因此,我们考虑维护每个环的异或和,塞入线性基中

再找一条链,去和其异或起来最小。即可。

这条链可以随便选择

简单证明一下;

假设存在两条链A,B,我们现在选择了不优的A链,但是在求解答案的时候(利用线性基)

我们会异或到一个环(A,B链围成的环),这时,就好比我们原路返回,又选择了较优的B链。

因此,这个题就解决了.

代码

#include<cstdio>
#include<algorithm>
#include<iostream>
#define R register
#define lo long long 

using namespace std;

const int gz=1e5+8;

inline void in(R int &x)
{
    int f=1;x=0;char s=getchar();
    while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    x*=f;
}

int head[gz<<1],tot;

struct cod{int u,v;lo w;}edge[gz<<2];

lo p[64],dis[gz];

inline void add(R int x,R int y,R lo z)
{
    edge[++tot].u=head[x];
    edge[tot].v=y;
    edge[tot].w=z;
    head[x]=tot;
}

int n,m;

bool vis[gz];

inline void ins(R lo x)
{
    for(R int i=63;i>=0;i--)
    {
        if((x>>i)&1LL)
        {
            if(p[i])
                x^=p[i];
            else 
            {
                p[i]=x;
                break;
            }
        }
    }
}

inline lo query(R lo o)
{
    R lo res=o;
    for(R int i=63;i>=0;i--)
        if((res^p[i])<res)res^=p[i];
    return res;
}

void dfs(R int u,R lo now)
{
    vis[u]=true;dis[u]=now;
    for(R int i=head[u];i;i=edge[i].u)
    {
        if(!vis[edge[i].v])
            dfs(edge[i].v,now^edge[i].w);
        else ins(now^edge[i].w^dis[edge[i].v]);
    }
}

int main()
{
    in(n);in(m);
    for(R int i=1,x,y;i<=m;i++)
    {
        R lo z;
        in(x),in(y);
        scanf("%lld",&z);
        add(x,y,z),add(y,x,z);
    }
    
    dfs(1,0);
    
    printf("%lld\n",query(dis[n]));
}
posted @   顾z  阅读(377)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 上周热点回顾(1.20-1.26)
点击右上角即可分享
微信分享提示