hdu5883【欧拉通路】

来源:互联网 发布:引用,指针和数组的区别 编辑:程序博客网 时间:2024/05/01 20:13

欧拉回路

对于一个图G存在这样一条路径,使它在所有边都经过一次,称这样的路径为欧拉路径。若该路径是一个圈,则称为是欧拉回路;

具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉路径但不具有欧拉回路的称为半欧拉图。

无向图存在欧拉回路的充要条件
当且仅当这个图的所有顶点的度数是偶数,且该图是连通图。

无向图含有欧拉通路的充要条件
当且仅当这个图有零个或两个奇数度的结点,且该图是连通图。

有向图存在欧拉回路的充要条件
所有顶点的 入度 和 出度 的和是 偶数,且该图是连通图。

有向图含有欧拉通路的充要条件
起始点s 的入度=出度-1,结束点t的出度=入度-1 或两个点的入度=出度,且该图是连通图。

题意:n个点m条无向边的图,找一个欧拉通路/回路,下标是p1,p2,p3…pt,然后使得ap1XORap2XOR…XORapt这个值最大。
思路:
首先要判断一下这个图是不是联通的,用并查集就好了,然后有个注意点就是可能是单个独立点;
然后再判断是不是欧拉通路,不是也不行;
最后计算,最后如果是欧拉回路还要找一个最大起点(终点)。

#include <bits/stdc++.h>using namespace std;const int N=1e5+10;int n;int pre[N];int a[N];int in[N];int Find(int x){    int r=x;    while(pre[r]!=r)        r=pre[r];    int i=x,j;    while(pre[i]!=r)    {        j=pre[i];        pre[i]=r;        i=j;    }    return r;}void Union(int x,int y){    int xx=Find(x);    int yy=Find(y);    if(xx!=yy)        pre[xx]=yy;}void init(){    for(int i=1;i<=n;i++)    {        scanf("%d",&a[i]);        pre[i]=i;        in[i]=0;    }}int main(){    int T,m,x,y;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        init();        for(int i=0;i<m;i++)        {            scanf("%d%d",&x,&y);            in[x]++;            in[y]++;            Union(x,y);        }        int flag=0;        for(int i=1;i<=n;i++)        {            if(pre[i]==i&&in[i])                flag++;            if(flag==2)                break;        }        if(flag==2)        {            puts("Impossible");            continue;        }        int res,num=0;        for(int i=1;i<=n;i++)        {            if(in[i]&1)                num++;        }        if(!(!num||num==2))        {            puts("Impossible");                continue;        }        int ans=0;        for(int i=1;i<=n;i++)        {            res=in[i];            if(res%2)            {                res/=2;                if((res+1)%2)                    ans^=a[i];            }            else            {                res/=2;                if(res%2)                    ans^=a[i];            }        }        //printf("%d\n",ans);        if(!num)        {            res=ans;            for(int i=1;i<=n;i++)            {                res=max(res,ans^a[i]);            }            printf("%d\n",res);        }        else            printf("%d\n",ans);    }    return 0;}
0 0