zoukankan      html  css  js  c++  java
  • 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);
    	}
    }
    
  • 相关阅读:
    如何快速查看archlinux pacman 软件记录?
    如何快速判断检查主机ip端口是否存活?
    如何在不清楚有哪些tag的情况下拉取docker镜像?
    如何使用docker版Openresty测试框架Test::Nginx进行测试?
    .net mvc4 使用 System.Web.Optimization 对javascript和style的引入、代码合并和压缩的优化(ScriptBundle,StyleBundle,Bund
    zen coding de 一些快捷功能
    C# Xpath
    一个SQL SERVER查询分析器非常好用的工具
    探索MSSQL执行计划
    博客园武林人士
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12852032.html
Copyright © 2011-2022 走看看