题面:https://www.luogu.org/problemnew/show/P3520
本题直接用跑欧拉回路找环即可。
Code:
#include<bits/stdc++.h>
using namespace std;
int t,ansn,n,m,dis[2200000],f[2200000],vis[120000];
int sum,num=-1,du[120000],first[2200000],nex[2200000],to[2200000];
void add(int u,int v)
{
nex[++num]=first[u];
to[num]=v;
first[u]=num;
}
void dfs(int u,int root)
{
f[++sum]=u;
du[u]-=2;
for(int i=first[u];i!=-1;i=nex[i])
{
first[u]=i;
if(dis[i]) continue;
dis[i]=dis[i^1]=1;
if(u!=root&&to[i]==root)
{
ansn++;
f[++sum]=to[i];
return;
}
dfs(to[i],root);
return;
}
}
int main()
{
memset(first,-1,sizeof(first));
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v,p,q;
scanf("%d%d%d%d",&u,&v,&p,&q);
if(p^q)
{
add(u,v);
add(v,u);
du[u]++;
du[v]++;
}
}
for(int i=1;i<=n;i++)
if(du[i]&1)
{
printf("NIE\n");
return 0;
}
for(int i=1;i<=n;i++)
{
if(!du[i]) continue;
while(du[i])
dfs(i,i);
}
printf("%d\n",ansn);
int i=1;
while(i<=sum)
{
int root=f[i],k=1;
i++;
while(f[i]!=root&&i<=sum)
k++,i++;
printf("%d ",k);
for(int j=i-k;j<=i;j++)
printf("%d ",f[j]);
printf("\n");
i++;
}
return 0;
}