[最小生成树]Planar graph 2022杭电多校第6场 1010

48 篇文章 0 订阅

Problem Description

We say an undirected graph is a planar graph, if it exists a way to draw it on a planar, such that no two edges have intersection except the endpoint. For example, the graph below is a planar graph:

But this graph below is not a planar graph, since it can be proved that no matter how to draw this graph on a planar, at least two edges have intersection which is not an endpoint:

For a planar graph, it has some areas separated by edges. For example, the planar graph below has 44 areas (Note that the area 11 is the infinite planar outside):

Give you a planar graph with nn vertices and mm edges. Each area sets a country. You are the designer and you want to build some tunnels on the edges such that: From one city, you can travel to any other city by going through some tunnels or passing some cities(i.e. you can't cross one edge unless it sets a tunnel). For example, for the graph above, you can build tunnels like this:

In the picture above, you can travel from city 22 to city 33 by going through tunnel 11, passing the city 11, then going through tunnel 33, passing the city 44, finally going through tunnel 22, and you can arrive to city 33. You can check that from any city you can travel to any other city.

You want the number of tunnels as small as possible. Print the minimum number of tunnels and the ID of edges you build tunnel on.

Input

The first line contains one integer T(1\le T\le 15)T(1≤T≤15), described the number of test cases.

For each test case:

The first line contains two integers n, m(1\le n\le 10^5, 0\le m\le 2\times 10^5)n,m(1≤n≤105,0≤m≤2×105) separated by a space, described the number of vertices and edges.

Next mm lines, the ii-th line contains two integers u, v(1\le u,v\le n)u,v(1≤u,v≤n), separated by a space, described the endpoint of the ii-th edge. The ID of the ii-th edge is ii.

It is guaranteed that the given graph is a planar graph. But this graph may have self-loop, parallel edge and the graph may not connected.

Output

The output contains 2T2T lines.

For each test case:

The first line contains one integer ff, described the minimum number of tunnels you have to build.

The second lines contains ff integers separated by spaces, the ii-th integer described the ID of edges the ii-th tunnel built on.

If for a fixed minimum number of tunnels, it has many ways to build the tunnels, print the lexicographically smallest answer.

Sample Input

1

5 7

1 1

1 2

1 3

3 4

3 4

2 4

2 5

Sample Output

3

1 2 4

题意: 给出一个n个点m条边的图,求使其不出现环所需要删除的最少边数以及删边方案中字典序最小的那个。

分析: 图可能是个不连通图,不过这并不影响我们解题,显然树这种结构就不会出现环,所以题目就是得到各连通分量的生成树,可以用kruskal算法跑一遍图,由于删边方案的字典序最小,所以需要先遍历编号大的边,也就是倒序遍历边集,当两点处于同一连通块内时记录答案。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;

int n, m, fa[100005];
struct edge{
	int u, v, w;
}e[200005];

int find(int x){
	if(x == fa[x]) return x;
	return fa[x] = find(fa[x]);
}

signed main()
{
	int T;
	cin >> T;
	while(T--){
		scanf("%d%d", &n, &m);
		for(int i = 1; i <= n; i++)
			fa[i] = i;
		for(int i = 1; i <= m; i++){
			int u, v;
			scanf("%d%d", &e[i].u, &e[i].v);
			e[i].w = i;
		}
		vector<int> ans;
		for(int i = m; i >= 1; i--){
			int u = e[i].u, v = e[i].v;
			if(find(u) != find(v))
				fa[find(u)] = find(v);
			else ans.push_back(e[i].w);
		}
		printf("%d\n", ans.size());
		for(int i = ans.size()-1; i >= 0; i--)
			printf("%d ", ans[i]);
		puts("");
	}
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值