您的位置:首页 > 其它

Educational Codeforces Round 27 G. Shortest Path Problem?(Guass异或线性基)

2017-09-14 18:18 731 查看

题目链接:Educational Codeforces Round 27 G. Shortest Path Problem?

题意:

有n个点,m条边,可能有自环,每条边有一个值,现在定义两点之间的距离为经过的边的异或值。

问从1到n的最短路是多少。

题解:

首先我们用一个dfs将每个环的异或值处理出来。

怎么处理呢,对于当前搜索到的点,如果之前已经访问过了,说明这里存在有环,然后将这个环的异或值存下来。

最后就会有tot个环的异或值,此时也会有一条到n的路径的值x。

现在问题就转换为在这tot个值中选择一个子集,使得x与选出来的子集进行异或,使得价值最小。

然后就可以用高斯来搞一下异或线性基,然后贪心一下就行了。

1 #include<bits/stdc++.h>
2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
3 using namespace std;
4 typedef pair<int,int>P;
5
6 const int N=1e5+7;
7 int a[N*2],tot,n,m,x,y,c,vis
,to
;
8 vector<P>e
;
9
10 void Gauss_xor(int *a,int n){
11     for(int u=1<<30,p=0,x;u;u>>=1){
12         for(x=++p;x<=n;++x)if(a[x]&u)break;
13         if(x>n){p--;continue;}swap(a

,a[x]); 14 F(i,1,n)if(i!=p&&(a[i]&u))a[i]^=a[p]; 15 } 16 } 17 18 void dfs(int x,int val) 19 { 20 vis[x]=1,to[x]=val; 21 for(auto it:e[x])if(vis[it.first]) 22 a[++tot]=to[x]^it.second^to[it.first]; 23 else dfs(it.first,val^it.second); 24 } 25 26 int main(){ 27 scanf("%d%d",&n,&m); 28 F(i,1,m) 29 { 30 scanf("%d%d%d",&x,&y,&c); 31 e[x].push_back(P(y,c)); 32 e[y].push_back(P(x,c)); 33 } 34 dfs(1,0),Gauss_xor(a,tot); 35 int ans=to ; 36 for(int i=1;a[i];i++)ans=min(ans,ans^a[i]); 37 printf("%d\n",ans); 38 return 0; 39 }

View Code [p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: