首页 > 其他分享 >Knights of the Round Table

Knights of the Round Table

时间:2023-09-26 17:15:25浏览次数:45  
标签:cnt ll dcc ele 奇环 Table rl Knights Round

prologue

相信很多人都感觉这个题不就是求一下这个二分图的最大独立集嘛,有什么难的,(劈里啪啦、库里跨啦、叮里哐啷)好,不对,好好好,题解!

analysis

这个题目实际上并不是一个完整的最大独立集问题,因为在这个题里面,是可以有相互仇恨的骑士的,只要不让他们二人坐成同桌就行。

那么我们就不如从正面来解决这个题。

首先,建立这个 憎恨 关系的 补图 从而得到一张 友善 关系图,这个时候肯定会形成环,我们进行下一步的思考。

之后,用 tarjan 将每个图所成一个点,之后对于每一个内部点数大于等于三的 V-DCC 进行判断内部是不是 奇环(题目中有描述,每次会议只能是奇数个人),如果这个环内部的数量不是奇数,那么这环内部的骑士就不能参与会议,属于要被除名的人。

对于判断每一个环是不是奇环,我们可以用 染色法,如果发生 冲突 则代表内部是合法的,如果成功染色,则是 非法 的。

同时还有一个重要结论虽然我不知道为什么重要,大佬说是就是点双连通图中若包含一个奇环,则所有点都在至少一个简单奇环上。

至于证明过程,大家可以前往巨佬的博客查看。

CODE TIME

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rl register ll

const ll N = 1010;

ll n, m;

ll dfn[N], low[N], top, timestamp, ans, tmp[N];

ll stk[N], dcc_cnt, dcc_size[N], col[N], root, now;

bool g[N][N], val[N], in_dcc[N], flag;

vector<ll> dcc[N];

inline void dfs(ll u, ll c)
{
	if(flag) return ;
	col[u] = c;
	for(rl i=1; i <= n; ++ i) if(g[u][i])
	{
		if(tmp[i] != now) continue;
		if(col[i]) if(col[i] == c) { flag = 1; return ;}
		if(!col[i]) dfs(i, 3 - c);
	}
}

inline void tarjan(ll u)
{
	stk[ ++ top] = u;
	dfn[u] = low[u] = ++ timestamp;
	
	for(rl v=1; v <= n; ++ v)
	{
		if(!g[u][v]) continue;
		if(!dfn[v])
		{
			tarjan(v), low[u] = min(low[u], low[v]);
			if(low[v] >= dfn[u])
			{
				dcc_cnt ++ ;
				ll ele;
				do {
					ele = stk[top -- ];
					dcc[dcc_cnt].push_back(ele), dcc_size[dcc_cnt] ++ ;
				} while(ele != v);
				dcc[dcc_cnt].push_back(u), dcc_size[dcc_cnt] ++;
			}
		}
		else low[u] = min(low[u], dfn[v]);
	}
}

inline void clean()
{
	for(rl i=1; i <= dcc_cnt; ++ i) dcc[i].clear();
	top = timestamp = dcc_cnt = ans = 0;
	memset(dcc_size, 0, sizeof dcc_size), memset(dfn, 0, sizeof dfn), memset(tmp, 0, sizeof tmp);
	memset(g, 0, sizeof g), memset(col, 0, sizeof col), memset(val, 0, sizeof val);
}

int main()
{
	while(cin >> n >> m, n)
	{
		clean();
		for(rl i=1; i <= n; ++ i) g[i][i] = 1;
		for(rl i=1; i <= m; ++ i)
		{
			ll a, b;
			cin >> a >> b;
			g[a][b] = g[b][a] = true;
		}
		
		for(rl i=1; i <= n; ++ i)
			for(rl j=1; j <= n; ++ j)
				g[i][j] ^= 1;
				
		for(root = 1; root <= n; ++ root)
			if(!dfn[root])
				tarjan(root);
		
		for(rl i=1; i <= dcc_cnt; ++ i)
		{
			now = i, flag = 0;
			for(rl j : dcc[i]) tmp[j] = now, col[j] = 0;
			dfs(dcc[i][0], 1);
			if(flag)
				for(rl j : dcc[i])
					val[j] = true;
		}
		
		for(rl i=1; i <= n; ++ i) ans += val[i];
			
		cout << n - ans << endl;
	}
	return 0;
}

标签:cnt,ll,dcc,ele,奇环,Table,rl,Knights,Round
From: https://www.cnblogs.com/carp-oier/p/17730505.html

相关文章

  • Codeforces Round 899 (Div. 2)
    CodeforcesRound899(Div.2)A.IncreasingSequence解题思路:从左往右一个个看,从1开始,如果当前位相同\(+2\),否则\(+1\)。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;constintN=1e6+10;constintM=2*M;constintmod=1e9+......
  • Educational Codeforces Round 155 D (CF1879_D)
    题目大意给一个长度为\(n\)的数组,求\(\Sigma_{i=1}^{n}\Sigma_{j=i}^{n}区间异或和\times(j-i+1)\)其中\(n\leq3e5,~a[i]\leq1e9\)分析首先注意到由\(l\)到\(r\)的区间异或和可以转化为\(sum_{l-1}~XOR~sum_r\)因此,对于每一个点\(x\),无论它作为上述的\(sum......
  • el-table表头动态渲染未更新
    问题el-table的表头改为通过获取后端数据动态渲染,发现在请求接口后,表头并未重新渲染。//html<el-table:data="tableData"><el-table-columnv-for="(item,index)intableCol":key="index"><templateslot="header">{{item.colN......
  • Educational Codeforces Round 155 (Rated for Div. 2)
    EducationalCodeforcesRound155(RatedforDiv.2)A.Rigged!解题思路:若存在\(s[i]>=s[1]\)并且\(e[i]>=e[i]\),那么答案为\(-1\).否则,答案为\(s[1]\).代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;constintN=1e6+10;con......
  • 牛客周赛 Round 11
    https://ac.nowcoder.com/acm/contest/64593A题签到B题值得说得是对非降序的理解:非降序表示数组中的前一个数要<=下一个数C题也算dp,因为需要注意遍历顺序,计算的是所有子串的的权重,我们知道枚举所有子串需要\(O(n^2)\)的复杂度,按照本题数据范围显然不能\(O(n^3)\),我们只能在枚......
  • CF_EduRound155小丑寄
    一句话总结:A题理解错了,数据又水,所以寄了。过程:22:35开题。22:40怎么还没加载出来??急急急22:42哦,严格大于,但是主宾对调了,乐乐乐乐乐乐乐,cout<<ans;\(\rightarrow\)cout<<ans-1;22:45一发过。。。22:45-23:38啥事没有。23:38开E题23:50左右好像有点思路......
  • Educational Codeforces Round 155 (Rated for Div. 2)
    比赛链接A.Rigged!题目链接就是一个比较简单的模拟就可以解决,如何判断能不能第一只需要考虑比他力量大的耐力是不是也比他大就行,而只要比他大,他就不可能第一,否则输出他的力量作为标杆就行,这样也可以避免比他力量小的也可以举起来。#include<bits/stdc++.h>usingnamespaces......
  • layui table 表格上下左右事件
    //按键监听事件$(document).on('keydown','.layui-input',function(event){vartd=$(this).parent('td');varindex=td.index();vartr=td.parent('tr');v......
  • Stable Diffusion 的工作原理
    StableDiffusion是一种深度学习技术,主要用于生成式对抗网络(GANs)的训练。这一技术旨在提高生成图像和视频的质量和稳定性。StableDiffusion引入了一种称为"masking"的功能,用于改进训练的效果。在本文中,我将详细介绍StableDiffusion中masking的具体含义,并通过示例来说明......
  • stable-diffusion-webui Github 代码仓库的介绍
    stable-diffusion-webui:一个基于Web的稳定梯度流生成模型训练工具stable-diffusion-webui是一个位于GitHub上的开源代码仓库,地址为https://github.com/AUTOMATIC1111/stable-diffusion-webui。该仓库提供了一个基于Web的用户界面,旨在简化使用StableDiffusion这一生成模......