跪dalao……
我们新建一个点0,连边向所有奇数度点,于是得到了一个偶数条边,所有点度数都是偶数的图
这个图存在欧拉回路,根据每次流出0,流入0的两个奇数点可以配对
但是这题要求路径长度为偶数,于是我们将n个点拆成2n个点,这样配对的奇数点之间的路径长度就是偶数了
我们现在想在2n个点中建入原图中的边,使所有点度数都为偶数
考虑怎么连原图中的边
0的度数显然为偶数
建出原图的生成树,对于不在生成树上的边,在二分图上随便建
然后对于生成树上的边 < fa,x>,
如果x的度数是奇数,连边< x,fa+n>
如果x的度数是偶数,连边< x+n,fa>
这样做能保证x的度数是偶数,因为拆点前x的度数是偶数,所以x+n的度数一定是偶数
于是我们能保证除了树根的两个点root,root+n,所有点的度数都是偶数
因为所有点的度数和是偶数,
droot,droot+n
一定同奇偶
若他们都为奇数,则存在一条root到root+n的欧拉回路(好吧不能叫回?
因为原图的总边数是偶数,根据二分图性质,从root走完所有边一定在root这边,不合法
所以这种情况不存在
于是所有点度数都是偶数
跑个欧拉回路就好了qaq
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void read(int &x)
{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 1010000;
const int maxm = 2010000;
int n,m;
int d[maxn],cnt[maxn],e[maxm][2];
struct edge{int y,c,nex;}a[maxm]; int len,fir[maxn];
inline void ins(const int x,const int y,const int c)
{
a[++len]=(edge){y,c,fir[x]};fir[x]=len;
a[++len]=(edge){x,c,fir[y]};fir[y]=len;
cnt[x]++,cnt[y]++;
}
int fa[maxn];
int findfa(const int x){return fa[x]==x?x:fa[x]=findfa(fa[x]);}
vector<int>V[maxn],vi[maxn];
void build(const int x,const int fa,const int fai)
{
for(int i=0;i<V[x].size();i++) if(V[x][i]!=fa)
build(V[x][i],x,vi[x][i]);
if(x==1) return;
if(cnt[x]&1) ins(x,fa+n,fai);
else ins(x+n,fa,fai);
}
bool use[maxm];
int t[maxm],tp;
void dfs(const int x)
{
for(int k=fir[x];k;k=fir[x])
{
while(k&&use[a[k].c]) k=a[k].nex;
if(!k) return;
use[a[k].c]=true;
fir[x]=a[k].nex;
dfs(a[k].y),t[++tp]=a[k].c;
}
}
int main()
{
read(n); read(m);
for(int i=1;i<=m;i++)
{
int x,y; read(x); read(y);
d[x]++,d[y]++;
e[i][0]=x,e[i][1]=y;
}
for(int i=1;i<=n;i++) if(d[i]&1)
ins(0,i,m+i);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
int x=e[i][0],y=e[i][1];
if(findfa(x)==findfa(y)) ins(x,y+n,i);
else
{
fa[findfa(x)]=findfa(y);
V[x].push_back(y),vi[x].push_back(i);
V[y].push_back(x),vi[y].push_back(i);
}
}
build(1,0,0);
dfs(0);
while(tp>0)
{
int ans1,ans2,ans3;
ans1=t[tp--]-m;
int j=tp;while(t[j]<=m) j--;
ans2=t[j]-m;
printf("%d %d %d\n",ans1,ans2,tp-j);
while(tp>j) printf("%d ",t[tp--]); putchar('\n');
tp--;
}
return 0;
}