Infiniti

   :: 首页  :: 新随笔  ::  ::  :: 管理

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;
}

  

posted on 2019-01-13 11:53  自由缚  阅读(187)  评论(0编辑  收藏  举报