bzoj2155(高斯消元,线性基)

Description
在这里插入图片描述
Input
第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。
Output
仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。
Sample Input
5 7
1 2 2
1 3 2
2 4 1
2 5 1
4 5 3
5 3 4
4 3 2
Sample Output
6
HINT
在这里插入图片描述
Source

就是很多个环和一个到n的路径中取个异或最大…
然后就是高斯消元的经典运用了.
也是线性基

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back 
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
namespace fastIO{
    #define BUF_SIZE 100000
    #define OUT_SIZE 100000
    bool IOerror = 0;
    inline char nc(){
        static char buf[BUF_SIZE],*p1 = buf+BUF_SIZE, *pend = buf+BUF_SIZE;
        if(p1 == pend){
            p1 = buf; pend = buf+fread(buf, 1, BUF_SIZE, stdin);
            if(pend == p1){ IOerror = 1; return -1;}
        }
        return *p1++;
    }
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline ll rd(){
        bool sign = 0; char ch = nc();ll x = 0;
        for(; blank(ch); ch = nc());
        if(IOerror)return 0;
        if(ch == '-') sign = 1, ch = nc();
        for(; ch >= '0' && ch <= '9'; ch = nc()) x = x*10+ch-'0';
        if(sign) x = -x;
        return x;
    }
    #undef OUT_SIZE
    #undef BUF_SIZE
};
using namespace fastIO;
int n , m , t , linkk[50100] , num;
struct node{int n,y;ll v;}e[201000];
ll a[101000],v[101000],fk;
bool vis[101000];
void insert()
{
    int x = rd(),y = rd();ll z = rd();
    e[++t].y = y;e[t].n = linkk[x];e[t].v = z;linkk[x] = t;
    e[++t].y = x;e[t].n = linkk[y];e[t].v = z;linkk[y] = t;
}
void dfs(int x,ll now,int fa)
{
    v[x] = now;vis[x] = true;
    if(x == n) fk = now;
    rept(i,x)
        if(e[i].y != fa)
            if(!vis[e[i].y])
                dfs(e[i].y,now^e[i].v,x);
            else if(v[e[i].y]!=-1)a[++num] = v[x]^v[e[i].y]^e[i].v;
    v[x] = -1;
}
void gus()
{
    n = num;int M = n;
    rep(i,1,n)
    {
        rep(j,i+1,n) if(a[j] > a[i]) swap(a[i],a[j]);
        int k;
        if(a[i] == 0) {M = i-1;break;}
        for(k=60;k>=0;--k) if(a[i]>>k&1) break;
        rep(j,1,n) if(i != j && (a[j]>>k&1)) a[j]^=a[i];
    }
    ll now = fk;
    rep(i,1,M) if((now ^ a[i]) > now) now ^= a[i];
    printf("%lld",now);
}
int main()
{
    n = rd();m = rd();
    rep(i,1,m) insert();
    dfs(1,0,0);
    gus();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a1035719430/article/details/82786269