HDU 5883 欧拉回路

题面:
这里写图片描述
思路:

这里面有坑啊啊啊…..
先普及一下姿势:

  1. 判断无向图欧拉路的方法:
    图连通,只有两个顶点是奇数度,其余都是偶数度的。

  2. 判断无向图欧拉回路的方法:
    图连通,所有顶点都是偶数度。

重点:图连通!!

思路:
先看看图是否联通(就是所有边都能经过么)
再判判是不是欧拉路
经过的次数=(du[i]+1)/2
如果是欧拉回路:枚举起点 再异或一下
不是:输出当前解

就酱~

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1000050
int n,t,m,xx[N],yy[N],h[N],ans,du[N],flg;
int first[N],nxt[N],v[N],tot;
bool vis[N],V[N];
void add(int x,int y){v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
void dfs(int x){
    for(int i=first[x];~i;i=nxt[i])if(!V[i])
        vis[v[i]]=1,V[i]=V[i^1]=1,dfs(v[i]);
}
int main(){
    scanf("%d",&t);
    while(t--){
        memset(first,-1,sizeof(first)),memset(vis,0,sizeof(vis));
        memset(V,0,sizeof(V));
        memset(du,0,sizeof(du)),flg=ans=tot=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&h[i]);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&xx[i],&yy[i]);
            du[xx[i]]++,du[yy[i]]++;
            add(xx[i],yy[i]),add(yy[i],xx[i]);
        }
        dfs(xx[1]),vis[xx[1]]=1;
        for(int i=0;i<tot;i++)if(!V[i])goto ed;
        for(int i=1;i<=n;i++){
            if(!vis[i])continue;
            if(du[i]&1)flg++;
            du[i]=(du[i]+1)/2;
            if(du[i]&1)ans=ans^h[i];
        }
        if(flg==2)printf("%d\n",ans);
        else if(!flg){
            int answer=0;
            for(int i=1;i<=n;i++)if(vis[i])
                answer=max(answer,ans^h[i]);
            printf("%d\n",answer);
        }
        else ed:puts("Impossible");
    }
}

这里写图片描述

posted @ 2016-10-06 20:20  SiriusRen  阅读(85)  评论(0编辑  收藏  举报