其他分享
首页 > 其他分享> > UVA10765 题解

UVA10765 题解

作者:互联网

题目传送门

显然,在 tarjan 的时候,假设遇到一个 \(dfn[u]\le low[v]\) 的节点,那么我们删去这个节点后一定会多出一个连通块,比如这样:

删去节点 \(5\) 后显然还剩下 \(3\) 个连通块,在这种情况下,我们看到节点 \(2,3\) 都满足上述条件,于是删去以后会多出来 \(2\) 个,加上原来的 \(1\) 个。

对于不是割点的,删去后一定还剩下一个。

于是我们就得出了以下结论

于是我们又可以发现其实第二个结论根本没必要,不是割顶一定满足不了 \(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;
}

标签:cnt,int,题解,UVA10765,dfn,low,删去,节点
来源: https://www.cnblogs.com/for-hyf/p/14855718.html