求职站外题
  • 板块灌水区
  • 楼主Black_Warrior
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/6/17 21:58
  • 上次更新2023/10/23 12:54:00
查看原帖
求职站外题
416139
Black_Warrior楼主2023/6/17 21:58

题目描述 给一个可能有自环和重边的无向图,输出最少的路径条数,使得每条边都恰好出现一次。

输入格式 从标准输入读入数据。

输入第一行包含两个正整数 nn 和 mm ,表示点数和边数,其中点用 11 到 nn 的正整数编号。保证 n≤105n\le 10^5,m≤3×105m\le 3\times10^5。

接下来 mm 行,每行包含两个正整数 uu 和 vv,表示一条边。保证 1≤u,v≤n1\le u,v\le n。

输出格式 输出到标准输出。

输出的行数等于需要的路径条数。

每行第一个整数为 ll,表示这条路径上边的条数,你需要保证它是正整数。接下来 l+1l+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;
}
2023/6/17 21:58
加载中...