1. 程式人生 > >BZOJ-8-2115: [Wc2011] Xor

BZOJ-8-2115: [Wc2011] Xor

tle bits con 思路 edge ++ nod get name

https://www.lydsy.com/JudgeOnline/problem.php?id=2115

題意 : 給出一個連通無向圖,求從1到n異或和最小的路徑.

思路 :隨意找一條簡單路徑 1-n 的,然後在這個過程中統計出 圖中的環

然後 ,對這些環的異或值求一下 線性基,最後 貪心去異或取最值即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 123456
ll n,m,head[maxn],cnt,w,u,v;
ll ans,p[maxn],len,dis[maxn];
bool vis[maxn];
vector<ll>ok;
struct node
{
    ll v,w,to;
} edge[maxn*2];
void add(ll u,ll v, ll w)
{
    edge[++cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].to=head[u];
    head[u]=cnt;
}
void dfs(int u,ll sum)
{
    vis[u]=1;
    dis[u]=sum;
    for(int i=head[u]; i!=-1; i=edge[i].to)
    {
        v=edge[i].v;
        w=edge[i].w;
        if(vis[v])ok.push_back(sum^dis[v]^w);
        else dfs(v,sum^w);
    }
}
void getj(ll x)
{
    for(int i=60; i>=0; i--)
    {
        if(!(x>>i))continue;
        if(!p[i])
        {
            p[i]=x;
            break;
        }
        else x^=p[i];
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%lld%lld",&n,&m);
    while(m--)
    {
        scanf("%lld%lld%lld",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }
    dfs(1,0);
    len=ok.size();
    for(int i=0; i<len; i++)
        getj(ok[i]);
    ans=dis[n];
    for(int i=60; i>=0; i--)
        if((ans^p[i])>ans)ans^=p[i];
    printf("%lld\n",ans);
    return 0;
}

  

BZOJ-8-2115: [Wc2011] Xor