题目描述 给一个可能有自环和重边的无向图,输出最少的路径条数,使得每条边都恰好出现一次。
输入格式 从标准输入读入数据。
输入第一行包含两个正整数 n 和 m ,表示点数和边数,其中点用 1 到 n 的正整数编号。保证 n≤105,m≤3×105。
接下来 m 行,每行包含两个正整数 u 和 v,表示一条边。保证 1≤u,v≤n。
输出格式 输出到标准输出。
输出的行数等于需要的路径条数。
每行第一个整数为 l,表示这条路径上边的条数,你需要保证它是正整数。接下来 l+1 个整数,依次给出路径上的点。相邻两个元素之间必须恰好用一个空格隔开,行末不能有多余的空格。
如果有多个可行答案,输出任何一个就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e6+10;
int n,m,ans[maxn],top,b[maxn],cnt[maxn][100],ans2[maxn],top2,vis[maxn],cntcnt;
struct node{
int to,id;
};
vector<node> a[maxn];
void dfs(int x,bool ok){
for(int &i=b[x];i<a[x].size();){
if(vis[a[x][i].id/2]){
i++; continue;
}
vis[a[x][i].id/2]=1;
dfs(a[x][i++].to,ok);
}
if(ok==0) ans[++top]=x;
else ans2[++top2]=x;
}
int main()
{
int u,v,x=2;
cin>>n>>m;
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
a[u].push_back({v,x++});
a[v].push_back({u,x++});
}
for(int i=1;i<=n;i++){
if(a[i].size()%2==1){
a[0].push_back({i,x++});
a[i].push_back({0,x++});
}
}
dfs(0,0);
int sum=0;
for(int i=top;i>=1;i--){
if(ans[i]==0) cnt[sum][0]=cntcnt,sum++,cntcnt=0;
else cnt[sum][++cntcnt]=ans[i];
}
int now=top;
for(int i=1;i<=sum;i++){
if(cnt[i][0]>0){
cout<<cnt[i][0]-1;
for(int j=cnt[i][0];j>=1;j--) cout<<" "<<cnt[i][j];
now-=cnt[i][0]+1;
cout<<endl;
}
}
for(int i=1;i<=n;i++){
if(vis[i]==0 && a[i].size()>0){
top2=0; dfs(i,1); cout<<top2-1;
for(int j=top2;j>=1;j--) cout<<" "<<ans2[j];
cout<<endl;
}
}
return 0;
}