UVA10765 题解
Posted all_WA
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 题解的主要内容,如果未能解决你的问题,请参考以下文章