The Best Path ( 欧拉图 及其性质 )

The Best Path ( 欧拉图 及其性质  )

Alice is planning her travel route in a beautiful valley. In this valley, there are N lakes, and M rivers linking these lakes. Alice wants to start her trip from one lake, and enjoys the landscape by boat. That means she need to set up a path which go through every river exactly once. In addition, Alice has a specific number (a1,a2,...,an) for each lake. If the path she finds is P0→P1→...→Pt, the lucky number of this trip would be aP0XORaP1XOR...XORaPt

. She want to make this number as large as possible. Can you help her?

Input

The first line of input contains an integer t

, the number of test cases. t test cases follow.

For each test case, in the first line there are two positive integers N (N≤100000) and M (M≤500000), as described above. The i-th line of the next N lines contains an integer ai(∀i,0≤ai≤10000) representing the number of the i-th lake.

The i-th line of the next M lines contains two integers ui and vi representing the i-th river between the ui-th lake and vi-th lake. It is possible that ui=vi

.

Output

For each test cases, output the largest lucky number. If it dose not have any path, output "Impossible".

Sample Input

2
3 2
3
4
5
1 2
2 3
4 3
1
2
3
4
1 2
2 3
2 4

Sample Output

2
Impossible

题意:有n个湖泊, m条小河, 每条小河连接两个湖泊。 现在Alice想要从一个湖泊出发坐着小船经过所有的小河一次且仅一次,如果可能输出经过点的异或和(  p0→p1→p2  ==  p0 xor p1 xor p2 ), 不可能输出Impossible。

前言:

1. 欧拉路:欧拉路是指从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边通过的且只通过一次

2. 欧拉回路:欧拉回路是指起点和终点相同的欧拉路。

3. 一个无向图存在欧拉路,当且仅当该图有0个或2个奇数度数的顶点,且该图是连通图。

4.一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。

5.一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。

6.一个有向图存在欧拉路:图连通,所有节点的出度等于入度;或者除两个节点以外的其余节点的入度和出度都相等,且这两个节点一个满足出度-入度==1,另一个满足入度--出度==1。

思路:这个题是个无向图判断是否是欧拉图。

首先,我们可以通过判断度的奇偶性来判断是否是 Impossible,因为欧拉路径存在两种,一种是欧拉通路,一种是欧拉回路。通路是起点、终点是不同点,那么我们需要将起点终点多算一次,并且起点和终点是固定的,必然是度为奇数的结点,那么我们也就知道了这种情况需要度为奇数的结点只有连个;回路呢,其实是起点、终点重合,变成了同一个点,所以呢,我们需要对这个起点多算一次即可了,但是这里起点不唯一,所以需要枚举起点。

那么问题来了,每个结点的异或次数是多少呢?实际上这个和度有关,因为我们可以想象的到的是,每次经过一个结点,除了起点和终点外,必然是一个入度和一个出度,想要让每条路都走一遍,需要把这些度都消费掉,那么每个结点的异或次数自然就是度数的一半了,然而这里还要一个小小的优化就是,异或不管次数再多,只有两种结果,一种是异或奇数次,一种是异或偶数次,因为偶数次的异或会抵消异或的效力,酱紫就好做很多了。这里需要注意的是,起点和终点多算一次异或也就行了。

所以呢,这里的第一个过程不考虑起点时,求得一个异或值后,接着在第二个过程加入起点和终点,如果是通路,就是固定起点和终点,比较容易解决,回路就需要遍历求最大值,而这里我们需要注意的是,插入起点后,结果可能比第一个过程的临时结果大,也可能小,所以需要格外注意取最的过程,不要以为只会变大哦~~~ ( 思路转载自肘子zhouzi )

 

代码:没判定图是否是连通的就给过了,可能数据全是连通图的

#include<bits/stdc++.h>

using namespace std;

const int maxn = 5e5+10;
int head[maxn];
int cnt,date[maxn],n,m;
int du[maxn];

int main()
{
    int listt;
    cin >> listt;
    while ( listt-- ) {
        memset(du,0,sizeof(du));
        memset(date,0,sizeof(date));
        cnt = 0;
        cin >> n >> m;
        for ( int i=1; i<=n; i++ ) {
            scanf("%d",&date[i]);
        }
        for ( int i=0; i<m; i++ ) {
            int u,v;
            scanf("%d %d",&u,&v);
            du[u] ++; du[v] ++;
        }
        int tot = 0,x1,x2;
        for ( int i=1; i<=n; i++ ) {
            if ( du[i]%2==1 ) {
                tot ++;
                du[i] ++; // 奇数度节点一定是起点或者终点,所有加一个进入和退出的度
            }
        }
        int ans = 0;
        for ( int i=1; i<=n; i++ ) {
            if ( du[i]/2%2==1 ) {   // 度数/2 是当前点会被便利几次, %2 是只有奇数次来会进行操作
                ans ^= date[i];
            }
        }
        if ( tot==1||tot>=3 ) { 
            printf("Impossible\n");
        }
        else if ( tot==2 ) {
            cout << ans << endl;
        }
        else {
            int maxx = ans;
            for ( int i=1; i<=n; i++ ) { // 从哪个点开始走,这个点就多算一次。 所有总值再异或一次。
                maxx = max(maxx,ans^date[i]);
            }
            cout << maxx << endl;
        }
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值