zoukankan      html  css  js  c++  java
  • RevolC FaeLoN UVA

    //这题图不一定联通,开始没看清,然后wa了几发。 
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N = 5010, M = 20010;
    int n, m;
    int h[N], e[M], ne[M], idx;
    int dfn[N], low[N], timestamp;
    //栈       栈顶
    int stk[N], top;
    //每个点属于哪个双连通分量
    int id[N];
    int dcc_cnt;
    //是不是桥
    bool is_bridge[M];
    //每个点度数
    int d[N];
    void add(int a, int b)
    {
    	e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
    }
    void tarjan(int u, int from)
    {
    	//初始化时间戳
    	dfn[u] = low[u] = ++ timestamp;
    	//入栈
    	stk[ ++ top] = u;
    	//遍历当前点的邻边
    	for (int i = h[u]; ~i; i = ne[i])
    	{
    		int j = e[i];
    		if (!dfn[j])
    		{
    			tarjan(j, i);
    			low[u] = min(low[u], low[j]);
    			//说明j到不了u
    			//说明是桥
    			if (dfn[u] < low[j])
    				is_bridge[i] = is_bridge[i ^ 1] = true;
    		}
    		//如果不是反向边
    		else if (i != (from ^ 1))
    			low[u] = min(low[u], dfn[j]);
    	}
    	if (dfn[u] == low[u])
    	{
    		++ dcc_cnt;
    		int y;
    		do
    		{
    			y = stk[top -- ];
    			id[y] = dcc_cnt;
    		}
    		while (y != u);
    	}
    }
    int main()
    {
    	while(cin>>n>>m)
    	{
    		memset(id,0,sizeof id);
    		memset(stk,0,sizeof stk);
    		memset(dfn,0,sizeof dfn);
    		memset(low,0,sizeof low);
    		memset(is_bridge,0,sizeof is_bridge);
    		memset(d,0,sizeof d);
    		dcc_cnt=timestamp=0;
    		idx=top=0;
    		memset(h, -1, sizeof h);
    		while (m -- )
    		{
    			int a, b;
    			cin >> a >> b;
    			add(a, b), add(b, a);
    		}
    		//防止搜反向边,所以要加-1(也就是从哪个边过来的)
    		for(int i=1;i<=n;i++)
    			if(!dfn[i])
    				tarjan(i,-1);
    		//找每个点的度数
    		//枚举所有边,找桥
    		for (int i = 0; i < idx; i ++ )
    			//如果是桥
    			if (is_bridge[i])
    				//那么就给出边所在的连通分量的编号度数++
    				d[id[e[i]]] ++ ;
    		//统计有多少度数为1的节点 ,(树中的叶节点)
    		if(dcc_cnt==1)
    		{
    			printf("0
    ");
    			continue;
    		}
    		int cnt = 0;
    		for (int i = 1; i <= dcc_cnt; i ++ )
    			if (d[i] == 1)
    				cnt ++ ;
    			else if(d[i]==0)
    				cnt+=2;
    		printf("%d
    ", (cnt + 1) / 2);
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:
    六、MySQL系列之数据备份(六)
    一:MySQL系列之基本介绍(一)
    第十一篇:面向对象之属性方法
    第十篇:面向对象系列之三大特性(二)
    Python开发之路:目录篇
    Linux基础知识(二)
    前端CSS规范整理
    如何使用BMap.Point传递变量、存储数据?
    百度地图API应用之获取用户的具体位置
    Bootstrap入门一:Hello Bootstrap
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12853535.html
Copyright © 2011-2022 走看看