P4151 [WC2011]最大XOR和路径

P4151 [WC2011]最大XOR和路径


一道妙极了的题。

首先直接从1走到n

然后现在图上有很多环

所以可以在走到n之后走到环上一个点,再走一遍环,再原路返回。这样就会xor上环的权值。

然后只需要把环搜出来就星了。

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
il ll gi(){
    rg ll x=0;rg char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x;
}
const int maxn=50000+10,maxm=100010<<1;
int n,m,fir[maxn],dis[maxm],nxt[maxm],id;ll w[maxm];
il vd link(int x,int y,ll z){nxt[++id]=fir[x],fir[x]=id,dis[id]=y,w[id]=z;}
ll p[64],dist[maxn];
il vd insert(ll x){
    for(rg int i=63;~i;--i)
        if((x>>i)&1){
            if(!p[i]){p[i]=x;break;}
            else x=x xor p[i];
        }
}
il vd dfs(int x,ll d){
    dist[x]=d;
    for(rg int i=fir[x];i;i=nxt[i])
        if(~dist[dis[i]])insert(d xor dist[dis[i]] xor w[i]);
        else dfs(dis[i],d xor w[i]);
}
int main(){
#ifdef xzz
    freopen("4151.in","r",stdin);
    freopen("4151.out","w",stdout);
#endif
    n=gi(),m=gi();ll x,y,z;
    while(m--)x=gi(),y=gi(),z=gi(),link(x,y,z),link(y,x,z);
    for(rg int i=1;i<=n;++i)dist[i]=-1;
    dfs(1,0);
    ll ans=dist[n];
    for(rg int i=63;~i;--i)ans=std::max(ans,ans xor p[i]);
    printf("%lld\n",ans);
    return 0;
}
posted @ 2018-04-04 18:57  菜狗xzz  阅读(252)  评论(0编辑  收藏  举报