• Knights of the Round Table POJ


    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio> 
    #include<vector>
    using namespace std;
    const int N = 1e3 + 10;
    const int M = 2e6 + 10;
    int n, m;
    int g[N][N];
    int h[N], e[M], ne[M], idx;
    int dfn[N], low[N], num, stac[N], top;
    int dcc_cnt;
    vector<int>dcc[N];
    bool cut[N];
    int c[N];
    int b[N];
    int color[N];
    bool ok;
    void add(int a, int b)
    {
    	e[idx] = b;
    	ne[idx] = h[a];
    	h[a] = idx ++;
    }
    void tarjan(int u, int root)
    {
    	dfn[u] = low[u] = ++num;
    	stac[++ top] = u;
    	if(u == root && h[u] == -1)
    	{
    		dcc[++dcc_cnt].push_back(u);
    		return ;
    	}
    	int cnt = 0;
    	for (int i = h[u]; ~i; i = ne[i])
    	{
    		int j = e[i];
    		if(!dfn[j])
    		{
    			tarjan(j, root);
    			low[u] = min(low[u], low[j]);
    			if(low[j] >= dfn[u])
    			{
    				cnt ++;
    				if(u != root || cnt > 1)
    					cut[u] = true;
    				dcc_cnt ++;
    				int z;
    				do
    				{
    					z = stac[top --];
    					dcc[dcc_cnt].push_back(z);
    				}
    				while(z != j);
    				dcc[dcc_cnt].push_back(u);
    			}
    		}
    		else low[u] = min(low[u], dfn[j]);
    	}
    }
    void dfs(int x, int co, int now)
    {
    	color[x] = co;
    	if(ok)
    		return ;
    	for (int i = h[x]; ~i; i = ne[i])
    	{
    		int j = e[i];
    		if(c[j] != now)
    			continue;
    		if(!color[j])
    		{
    			dfs(j, 3 - co, now);
    		}
    		//说明存在奇数环
    		else if(color[j] == color[x])
    		{
    			ok = true;
    			return ;
    		}
    	}
    }
    void init()
    {
    	num = 0;
    	idx = 0;
    	dcc_cnt = 0;
    	for (int i = 1; i <= n; i ++)
    	{
    		low[i] = dfn[i] = 0;
    		h[i] = -1;
    		dcc[i].clear();
    		cut[i] = 0;
    		b[i] = 0;
    		c[i] = 0;
    		color[i] = 0;
    		for (int j = i + 1; j <= n; j ++)
    		{
    			g[i][j] = g[j][i] = 0;
    		}
    	}
    }
    int main()
    {
    
    	while(scanf("%d%d", &n, &m) != EOF)
    	{
    		if(n == 0 && m == 0)
    			break;
    		init();
    		while(m --)
    		{
    			int x, y;
    			scanf("%d%d", &x, &y);
    			g[x][y] = g[y][x] = 1;
    		}
    		for (int i = 1; i <= n; i ++)
    			for (int j = i + 1; j <= n; j ++)
    				if(!g[i][j])
    					add(i, j), add(j, i);
    		for (int i = 1; i <= n; i ++)
    			if(!dfn[i])
    				tarjan(i, i);
    		for (int i = 1; i <= dcc_cnt; i ++)
    		{
    			for (int j = 0; j < dcc[i].size(); j ++)
    			{
    				int x = dcc[i][j];
    				//当前属于的连通块,因为每个点可能属于多个双连通分量
    				c[x] = i;
    				color[x] = 0;
    			}
    			ok = false;
    			dfs(dcc[i][0], 1, i);
    			//如果存在奇数环
    			if(ok)
    			{
    				//那么这个连通块中的所有的点 就都属于某个奇数环
    				for (int j = 0; j < dcc[i].size(); j ++)
    					b[dcc[i][j]] = 1;
    			}
    		}
    		int ans = 0;
    		for (int i = 1; i <= n; i ++)
    			if(!b[i])
    				ans ++;
    		printf("%d
    ", ans);
    	}
    }
    
  • 相关阅读:
    ParamCount、ParamStr
    写一个可拖动的 TShape 回复 "韦韦" 的问题
    读十六进制文本到 Btye 数组的函数 回复 "峰哥!!!" 的问题
    网站速度优化
    [新功能]新增分类浏览页面
    [CN.Text开发笔记]嵌套Repeater的问题
    中秋祝福
    10 Golden rules for publishing your blog
    HttpCompressionModule 6的一个Bug及使用效果
    [CN.Text开发笔记]OnInit与运行期数据绑定
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12852032.html
Copyright © 2020-2023  润新知