码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2115

时间:2017-07-02 18:32:17      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:pac   void   bzoj2115   ret   lap   ++i   swap   code   back   

线性基+dfs树

我们先搞出dfs树,其实最终路径就是最初的路径和一些环异或。

环最多只有m-n+1,因为一共有m条边,然后有n-1条边在dfs树上,所以还剩m-n+1条边,都可以构成环。

所以dfs搞出环,线性基找最大值就可以了。

技术分享
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, ll> PII;
const int N = 200010;
int n, m, cnt;
vector<PII> G[N];
ll a[N], d[N];
int used[N];
void gauss()
{
    int now = 1;
    for(int i = 62; i >= 0; --i)
    {    
        bool flag = false;
        for(int j = now; j <= cnt; ++j) 
            if(a[j] & (1ll << i)) 
            {
                swap(a[j], a[now]);
                flag = true;
                break;
            }
        if(!flag) continue;
        for(int j = 1; j <= cnt; ++j) if((a[j] & (1ll << i)) && j != now)    
            a[j] ^= a[now];
        ++now;
    }
    --now;
}
void dfs(int u, int last)
{
    used[u] = 1;
    for(int i = 0; i < G[u].size(); ++i)
    {
        PII x = G[u][i];
        int v = x.first;
        ll w = x.second;
        if(v == last) continue;
        if(!used[v]) 
        {    
            d[v] = d[u] ^ w;
            dfs(v, u);
        }
        else a[++cnt] = d[v] ^ d[u] ^ w;
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i)
    {
        int u, v;
        ll w;
        scanf("%d%d%lld", &u, &v, &w);
        G[u].push_back(make_pair(v, w));
        G[v].push_back(make_pair(u, w));
    }
    dfs(1, 0);
    ll ans = d[n];
    gauss();
    for(int i = 1; i <= 62 && i <= cnt; ++i) if((ans ^ a[i]) > ans)
        ans ^= a[i];
    printf("%lld\n", ans);
    return 0;
} 
View Code

 

bzoj2115

标签:pac   void   bzoj2115   ret   lap   ++i   swap   code   back   

原文地址:http://www.cnblogs.com/19992147orz/p/7106675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!