51nod1967 路径定向(欧拉回路+结论题)
Posted Sakits
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod1967 路径定向(欧拉回路+结论题)相关的知识,希望对你有一定的参考价值。
看到入度等于出度想到欧拉回路。
我们把边都变成无向边,有一个结论是偶数度的点都可以变成出入度相等的点,而奇数点的不行,感性理解分类讨论一下就知道是对的。
还有一个更好理解的结论是变成无向边后奇数点的个数一定只有偶数个,因为有一个奇数点就一定有另一个跟他对应。
那么我们把奇数点凑成对连边,这样奇数点也变成了偶数点。无向图中所有的点的度数为偶数就存在欧拉回路,于是我们就可以跑一遍欧拉回路途中判断边是否需要返向来得到方案。
卡常题T T(其实是我写太丑
#include<stdio.h> #include<iostream> #include<cstring> #include<cstdlib> using namespace std; const int maxn=1000010; struct poi{int x,too,pre,pos;}e[maxn<<1]; int n,m,x,y,cnt,tot,cntt; int d[maxn],p[maxn],last[maxn],flag[maxn<<1],v[maxn]; char buf[80000010],*ptr=buf-1; inline int read() { char c=*++ptr;int s=0,t=1; while(c<48||c>57)c=*++ptr; while(c>=48&&c<=57){s=s*10+c-‘0‘;c=*++ptr;} return s*t; } inline void add(int x,int y,int z,int from){e[++tot].x=from;e[tot].too=y;e[tot].pos=z;e[tot].pre=last[x];last[x]=tot;} void dfs(int x) { v[x]=1; for(register int i=last[x];i;last[x]=i=e[i].pre) if(!flag[e[i].pos]) { if(e[i].x==x)flag[e[i].pos]=1; else flag[e[i].pos]=2; dfs(e[i].too); } } int main() { fread(buf,1,sizeof(buf),stdin); n=read();m=read(); for(register int i=1;i<=m;++i) { x=read();y=read(); if(x==y)continue; add(x,y,i,x);add(y,x,i,x); d[x]++;d[y]++; } for(register int i=1;i<=n;++i)if(d[i]&1)p[++cnt]=i; for(register int i=1;i<=cnt;i+=2)add(p[i],p[i+1],(i>>1)+m+1,p[i]),add(p[i+1],p[i],(i>>1)+m+1,p[i]); for(register int i=1;i<=n;++i)if(!v[i])dfs(i); printf("%d\n",n-cnt); for(int i=1;i<=m;i++)if(flag[i]==1)putchar(‘0‘);else putchar(‘1‘); }
以上是关于51nod1967 路径定向(欧拉回路+结论题)的主要内容,如果未能解决你的问题,请参考以下文章