UVA10765 题解
2021/6/6 18:29:26
本文主要是介绍UVA10765 题解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目传送门
显然,在 tarjan 的时候,假设遇到一个 \(dfn[u]\le low[v]\) 的节点,那么我们删去这个节点后一定会多出一个连通块,比如这样:
删去节点 \(5\) 后显然还剩下 \(3\) 个连通块,在这种情况下,我们看到节点 \(2,3\) 都满足上述条件,于是删去以后会多出来 \(2\) 个,加上原来的 \(1\) 个。
对于不是割点的,删去后一定还剩下一个。
于是我们就得出了以下结论
-
对于割点:每满足有一个 \(dfn[u]\le low[v]\) 的节点,删去后的连通块就多一个。
-
对于其他节点:删去后一定只剩一个。
于是我们又可以发现其实第二个结论根本没必要,不是割顶一定满足不了 \(dfn[u]\le low[v]\)。
最后因为要序号小的在前,我们直接用结构体存下来就好了。
Code:
#include<iostream> #include<vector> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e4+5; vector <int> G[maxn]; int dfn[maxn],low[maxn]; struct dat{ int w,id; bool operator <(const dat& rhs)const{ if(w>rhs.w)return true; if(w==rhs.w)return id<rhs.id; return false; } }cnt[maxn]; int num; void tarjan(int u,int pa){ dfn[u]=low[u]=++num; int ch=0; for(int i=0;i<G[u].size();++i){ int v=G[u][i]; if(!dfn[v]){ tarjan(v,u); low[u]=min(low[u],low[v]); if(dfn[u]<=low[v]){ if(++ch>1||u!=1)cnt[u].w++; } } else if(v!=pa)low[u]=min(dfn[v],low[u]); } } int main(){ int n,m; while(cin>>n>>m&&n&&m){ int u,v; memset(dfn,0,sizeof(dfn)); memset(cnt,0,sizeof(cnt)); for(int i=0;i<=n;++i){ G[i].clear(); cnt[i].id=i; } while(cin>>u>>v&&u>=0&&v>=0){ G[u].push_back(v); G[v].push_back(u); } tarjan(1,0); sort(cnt,cnt+n); for(int i=0;i<m;++i) cout<<cnt[i].id<<" "<<cnt[i].w+1<<endl; cout<<endl; } return 0; }
这篇关于UVA10765 题解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南