频道栏目
首页 > 资讯 > 其他 > 正文

无向图最小路径覆盖

18-08-01        来源:[db:作者]  
收藏   我要投稿

The Wall has down and the King in the north has to send his soldiers to sentinel.
The North can be regard as a undirected graph (not necessary to be connected), one soldier can cover one path. Today there's no so many people still breathing in the north, so the King wants to minimize the number of soldiers he sent to cover each edge exactly once. As a master of his, you should tell him how to arrange soldiers.

Input

There might be multiple test cases, no more than 20. You need to read till the end of input.
In the first line, two integers n and m, representing the number of nodes and edges in the graph.
In the following m lines, each contain two integers, representing two ends of an edge.
There are no parallel edges or self loops.
1≤n,m≤100000

Output

For each test case, the first line contains number of needed routes, p.
For the following p lines, an integer x in the beginning, followed by x integers, representing the list of used edges. Every integer should be a positive or negative integer. Its absolute value represents the number of chosen edge (1~n). If it's positive, it shows that this edge should be passed as the direction as the input, otherwise this edge should be passed in the direction different from the input. Edges should be in correct order.

Sample Input

3 3
1 2
1 3
2 3

Sample Output

1
3 1 3 -2

题意:

给出一张无向图,求最少几笔画完所有的边,并输出路径(反向边输出-(编号))

思路:

1:建图

2:搜索联通块和度数为奇数的点

3:在每个奇数度的点内加额外边

4:DFS得到结果

一张连通图需要n笔画完,则n=max( Deg(奇数)的个数/2,1)

试想每次添加一条边,总度数+2,当有新的笔画出现,则说明出现了一个起点和终点,

也就是度数为奇数的点

当图上至多只有一对奇数度的点时,便可以一笔走过所有的边

删除额外添加的边 (序号>2*m+1)得到结果

#include
#include
#include
#include
using namespace std;
const int N = 100005;
struct node{
	int v;
	int able;
	int next;	
}edge[N*4];//要多于总边数的4倍(*2双向边 并且可能加边) 
int head[N],cnt;
int n,m,
res;//找到的路径数 
int vis[N],
deg[N]; //没点的度数 
vectorst;  //保存一个联通块中度数为奇数的点 
vectorroad[N];
void init(){
	res=0;
	cnt=1;
	memset(vis,0,sizeof(vis));
	memset(head,0,sizeof(head));
	memset(deg,0,sizeof(deg));
}
void add(int u,int v){
	edge[++cnt].next=head[u];
	edge[cnt].able=1;
	edge[cnt].v=v;
	head[u]=cnt;
	deg[u]++;
}
void add_Edge(int u,int v){
	add(u,v);
	add(v,u);
}
void DFS(int s){
	vis[s]=1;
	if(deg[s]&1) st.push_back(s);
	for(int i=head[s];i;i=edge[i].next){
		int v=edge[i].v;
		if(!vis[v]) DFS(v);
	}
}
void DFS2(int s){
	for(int i=head[s];i;i=edge[i].next){
		if(edge[i].able){
			edge[i].able=edge[i^1].able=false;
			DFS2(edge[i].v);
			if(i>2*m+1) ++res;//说明此边是由奇数点添加得到,所以这条回路已经结束 
			else road[res].push_back(i/2*(2*(i&1)-1));
		}
	}
}
int main(){
 while(~scanf("%d%d",&n,&m)){
 	init();
 	for(int i=0;i
相关TAG标签
上一篇:MySQL异步复制、全同步复制与半同步复制的实现和配置教程
下一篇:用单例模式来设计一个打印机
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站