当前位置:网站首页>(2022杭电多校六)1010-Planar graph(最小生成树)
(2022杭电多校六)1010-Planar graph(最小生成树)
2022-08-08 23:06:00 【AC__dream】
题目:
题意:给n个点和m条边,m条边将一个图分成若干个连通区域,然后我们可以删除一些边,问至少删除多少条边才能使得所有的区域是连通的,在所有的删边情况中选择字典序最小的一种情况进行输出。
先来思考一下,什么情况下才能使得所有区域是连通的?其实画个图观察不难发现,只有当图中没有环时整个区域才是连通的,现在问题就转化为我们至少删除多少条边才能使得图中没有环,由于树是一个没有环的最大连通子图,所以显然是将图删边使其形成一棵树,这样的话删除的边数一定是最小的,由于题目中要求删除的边的字典序最小,那么我们就可以考虑从编号大的边开始添加边,只要加进去该边不成环就把该边加入图中,这样最后没有加入图中的边就是我们要删除的边,那么我们直接按照字典序进行从小到大输出即可,这个过程就是利用类似kruscal的过程进行实现,只是我们不是按照边权进行排序,而是按照编号进行排序。
下面是代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<cmath>
using namespace std;
const int N=2e6+10;
int fu[N],u[N],v[N];
int find(int x)
{
if(x!=fu[x]) fu[x]=find(fu[x]);
return fu[x];
}
stack<int>st;
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) fu[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d",&u[i],&v[i]);
for(int i=m;i>=1;i--)
{
int fx=find(u[i]),fy=find(v[i]);
if(fx==fy)
st.push(i);
else
fu[fx]=fy;
}
printf("%d\n",st.size());
while(!st.empty())
{
printf("%d ",st.top());
st.pop();
}
puts("");
}
return 0;
}
边栏推荐
猜你喜欢
随机推荐
使用Mongoose populate实现多表关联存储与查询,内附完整代码
LeetCode:最长有效括号
sess.restore() 和 tf.import_meta_graph() 在使用时的一些关联
iptables firewall content full solution
请问:支付宝上买基金安全吗
JSDay1-合并两个有序数组
想要精准营销,从学习搭建一套对的标签体系开始丨DTVision分析洞察篇
Button Wizard Delete File Command
Low-Light Image Enhancement via a Deep Hybrid Network阅读札记
wps备份与恢复在哪里?
(2022牛客多校五)B-Watches(二分)
Kubernetes与OpenStack
关于OD的bp send断点 常用断点(OD)
stm32使用spi1在slave 模式下 dma 读取数据
ArcPy spot number - automatically fill according to field length
JS中数组扁平化的几种方法
ArcPy设置全库唯一标识码
微信小程序开发一些函数使用方法
wps表格怎么调整表格大小?wps表格调整表格大小的方法
每日一R「01」跟着大佬学 Rust