站外题求助(玄关)
  • 板块学术版
  • 楼主zjy102512
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/7/24 14:27
  • 上次更新2024/7/24 15:21:36
查看原帖
站外题求助(玄关)
931394
zjy102512楼主2024/7/24 14:27

小明在学校的编程课上了解到了关于二分图的相关知识,所谓的二分图是一种特殊的图,图中的所有顶点可以分为两个不相交的集合,而图中的所有边的两个顶点都分属于这两个集合。

换句话来说,二分图是可以进行黑白染色的图,即给图中所有顶点都涂上黑色或者白色,使得每条边的两个端点都异色。

现在小明想知道,对于任意的一个 n个顶点 m条边的无向图,通过删去一条边使其变为二分图的方案数是多少?

输入输出格式 输入格式:

第一行输入两个数 n、 m,表示图的顶点数和边数 接下来 m行,每行两个数 x、 y表示一条边(编号1~m) 输出格式:

第一行输出一个数 k,表示答案方案数 第二行输出 k个数,表示 k条边的编号,升序排列
输入样例: 9 12 1 2
1 3
2 4
2 5
3 5
4 6
4 7
5 7
6 8
7 8
7 9
8 9
可以用这个生成图
输出样例:

2
11 12
我的代码:

#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000005;
int n,m;
int f[maxn];
int dis[maxn];
priority_queue<int,vector<int>,greater<int> >ans;
struct node
{
	int num,c;
};
bool check[maxn];
queue<node>q;
int vis[maxn];
struct edge
{
	int to,nxt;
	int k;
};
edge e[maxn];
int head[maxn];
int cnt=0;
void add(int u,int v,int p)
{
	cnt++;
	e[cnt].to=v;
	e[cnt].nxt=head[u];
	e[cnt].k=p;
	head[u]=cnt;
}
bool bfs()
{
//	cout<<'a'<<endl;
	memset(check,0,sizeof(check)); 
	memset(vis,0,sizeof(vis));
	node s;
	s.c=1;
	s.num=1;
	vis[s.num]=1;
	q.push(s);
	while(!q.empty())
	{
		node tmp=q.front();
		q.pop();
		int u=tmp.num;
		int f=tmp.c;
		check[u]=1;
		for(int i=head[u];i!=-1;i=e[i].nxt)
		{
			int v=e[i].to;
			if(v==0)
			{
				continue;
			}
			if(vis[v]==0)
			{
				if(f==1)
				{
					vis[v]=2;
				}
				if(f==2)
				{
					vis[v]=1;
				}
			}
			else
			{
				if(vis[v]==f)
				{
					return false;
				}
			}
			if(check[v]==1)
			{
				continue;
			}
			node x;
			x.c=vis[v];
			x.num=e[i].to;
			q.push(x);
		}
	}
	return true;
}
void dfs(int u,int fa) 
{
//	
	dis[u]=1;
	for(int i=head[u];i!=-1;i=e[i].nxt)
	{
		if(e[i].to==fa)
		{
			continue;
		}
		if(dis[e[i].to]==2)
		{
			continue;
		}
		if(dis[e[i].to]==1)
		{
			int t=e[i].to;
			e[i].to=0;
//			cout<<fa<<" "<<u<<endl;
			if(bfs())
			{
			//	
				ans.push(e[i].k);
			}
			e[i].to=t;
			continue;
		}
		dfs(e[i].to,u);
	}
	dis[u]=2;
	return;
}
int main()
{
	memset(head,-1,sizeof(head));
	memset(dis,0,sizeof(dis));
	cin>>n>>m;
	int u,v;
	for(int i=1;i<=m;i++)
	{
		cin>>u>>v;
		add(u,v,i);
		add(v,u,i);
	}
	dfs(1,-1);
	cout<<ans.size()<<'\n';
	while(!ans.empty())
	{
		cout<<ans.top()<<' ';
		ans.pop();
	}
	return 0;
}
2024/7/24 14:27
加载中...