[CSP-S模拟测试]:简单的操作(二分图+图的直径)

题目描述

从前有个包含$n$个点,$m$条边,无自环和重边的无向图。
对于两个没有直接连边的点$u,v$,你可以将它们合并。具体来说,你可以删除$u,v$及所有以它们作为端点的边,然后加入一个新点$x$,将它与所有在原图中与u或v有直接连边的点连边。
你需要判断是否能通过若干次合并操作使得原图成为一条链,如果能,你还需要求出这条链的最大长度。


输入格式

从文件$merge.in$中读入数据。
第一行两个正整数$n,m$,表示图的点数和边数。
接下来m行,每行两个正整数$u,v$,表示$u$和$v$之间有一条无向边。


输出格式

输出到文件$merge.out$中。
如果能通过若干次合并操作使得原图成为一条链,输出链的最大长度,否则输出$-1$。


样例

样例输入1:

5 4
1 2
2 3
3 4
3 5

样例输出1:

3

样例输入2:

4 6
1 2
2 3
1 3
3 4
2 4
1 4

样例输出2:

-1


数据范围与提示

对于$30\%$的数据,$n<10$
对于$70\%$的数据,$n<2,000$
对于$100\%$的数据,$n\leqslant 1,000,m\leqslant 10^5$


题解

画画图便会发现,如果出现奇环则一定无解;最长链即为图的直径,答案就是每一个联通块直径和。

二分图染色即可,再求图的直径就好了。

时间复杂度:$\Theta(n^2)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct rec{int nxt,to;}e[200001];
int head[1001],cnt,tot;
int col[1001],bel[1001],len[1001];
int dis[1001];
bool vis[1001];
int ans;
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
void add(int x,int y)
{
	e[++cnt].nxt=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
void dfs(int x,int c,int p)
{
	col[x]=c;bel[x]=p;
	for(int i=head[x];i;i=e[i].nxt)
	{
		if(!col[e[i].to])dfs(e[i].to,-c,p);
		if(col[x]==col[e[i].to]){puts("-1");exit(0);}
	}
}
int Dij(int x)
{
	int res=0;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[x]=0;
	q.push(make_pair(0,x));
	while(!q.empty())
	{
		int flag=q.top().second;
		q.pop();
		if(vis[flag])continue;
		vis[flag]=1;
		res=max(res,dis[flag]);
		for(int i=head[flag];i;i=e[i].nxt)
			if(dis[e[i].to]>dis[flag]+1)
			{
				dis[e[i].to]=dis[flag]+1;
				q.push(make_pair(dis[e[i].to],e[i].to));
			}
	}
	return res;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	for(int i=1;i<=n;i++)
		if(!col[i])dfs(i,1,++tot);
	for(int i=1;i<=n;i++)
		len[bel[i]]=max(len[bel[i]],Dij(i));
	for(int i=1;i<=tot;i++)
		ans+=len[i];
	printf("%d",ans);
	return 0;
}


rp++

原文地址:https://www.cnblogs.com/wzc521/p/11670807.html

时间: 2024-08-30 15:48:12

[CSP-S模拟测试]:简单的操作(二分图+图的直径)的相关文章

「10.13晚」简单的序列(DP)&#183;简单的期望(DP)&#183;简单的操作(二分图+最短路)

A. 简单的序列 一道$DP$题,容易想到卡特兰数 考虑$n-m$的范围很小,显然我们可以将他们拼起来, 怎么拼???? 然后我们可以枚举在$s$左侧放了多少个括号 假如我们将左括号看成$+1$,右括号看成$-1$,两边保证前缀大于$0$,且后缀小于$0$, 然后注意给出的$s$序列化简之后的情况,于是就愉快的获得$100$的好成绩 我会告诉你我$T1$打了快两个小时才$A$掉吗? B. 简单的期望 神仙DP. 考场完全没想到,事实是因为根本没想.... 考虑分解的二的个数,其实就是该数在二进制

[CSP-S模拟测试]:简单的期望(DP)

题目描述 从前有个变量$x$,它的初始值已给出. 你会依次执行$n$次操作,每次操作有$p\%$的概率令$x=x\times 2$,$(100−p)\%$的概率令$x=x+1$. 假设最后得到的值为$w$,令$d$为$w$的质因数分解中$2$的次数,求$d$的期望. 输入格式 从文件$exp.in$中读入数据. 第一行三个整数$x,n,p$,含义见题目描述. 输出格式 输出到文件$exp.out$中. 一行一个实数,表示$d$的期望. 如果你的答案与标准答案的误差不超过$10^{−6}$,则判定

[CSP-S模拟测试]:简单的括号序列(组合数)

题目传送门(内部题82) 输入格式 一行一个字符串$ss$,保证$ss$中只包含$'('$和$')'$. 输出格式 一行一个整数,表示满足要求的子序列数对$10^9+7$的结果. 样例 样例输入1: )(()() 样例输出1: 6 样例输入2: ()()() 样例输出2: 7 样例输入3: ))) 样例输出3: 0 数据范围与提示 样例解释: 第一组样例中,有以下几种子序列满足条件(字符串下标从$1$计数): 删除$1,5$位置的字符,得到$(())$ 删除$1,2,3,4$位置的字符,得到$(

[CSP-S模拟测试]:简单的区间(分治)

题目描述 给定一个长度为$n$的序列$a$以及常数$k$,序列从$1$开始编号.记$$f(l,t)=\sum \limits_{i=l}^ra_i-\max \limits_{i=l}^r\{a_i\}$$求合法的正整数对$(l,r)$的数量,满足$1\leqslant l<r\leqslant n$,且$k|f(l,r)$. 输入格式 第一行两个正整数$n$和$k$. 第二行包含$n$个正整数,第$i$个正整数表示$a_i$. 输出格式 一行一个正整数,表示答案. 样例 样例输入1: 4 3

[CSP-S模拟测试]:简单的玄学(数学)

题目描述 有$m$个在$[0,2^n)$内均匀随机取值的整型变量,球至少有两个变量取值相同的概率.为了避免精度误差,假设你的答案可以表示成$\frac{a}{b}$的形式,(其中$(a,b)=1$),你需要输出$a$和$b$对${10}^6+3$取模后的值. 输入格式 第一行两个正整数$n,m$. 输出格式 一行两个整数,它们的含义如题所述. 样例 样例输入1: 3 2 样例输出1: 1 8 样例输入2: 1 3 样例输出2: 1 1 样例输入3: 4 3 样例输出3: 23 128 数据范围与

[CSP-S模拟测试]:简单的填数(贪心+模拟)

题目描述 对于一个长度为$n$,且下标从$1$开始编号的序列$a$,我们定义它是「合法的」,当且仅当它满足以下条件:·$a_1=1$·对于$i\in [1,n),a_i\leqslant a_{i+1}\leqslant a_i+1$且$a_{i+1}$为正整数·对于任意在$a$中出现过的数$v$,记它的出现次数为$s$,则$2\leqslant s\leqslant 5$给定一个长度为$n$的序列$a$,其中有一些位置为$0$,你需要在这些位置上任意填数,使得$a$成为一个合法的序列,并且最大

Android单元测试与模拟测试详解

测试与基本规范 为什么需要测试? 为了稳定性,能够明确的了解是否正确的完成开发. 更加易于维护,能够在修改代码后保证功能不被破坏. 集成一些工具,规范开发规范,使得代码更加稳定( 如通过 phabricator differential 发diff时提交需要执行的单元测试,在开发流程上就可以保证远端代码的稳定性). 2. 测什么? 一般单元测试: 列出想要测试覆盖的异常情况,进行验证. 性能测试. 模拟测试: 根据需求,测试用户真正在使用过程中,界面的反馈与显示以及一些依赖系统架构的组件的应用测

微信在线信息模拟测试工具(基于Senparc.Weixin.MP)

目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具在线DEMO:http://weixin.senparc.com/SimulateTool Senparc.Weixin.MP是一个开源的微信SDK项目,地址:https://github.com/JeffreySu/WeiXinMPSDK (其中https://github.com/Jeffrey

Mock 模拟测试简介及 Mockito 使用入门

Mock 是什么 mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法.这个虚拟的对象就是mock对象.mock对象就是真实对象在调试期间的代替品. 简单的看一张图 我们在测试类 A 时,类 A 需要调用类 B 和类 C,而类 B 和类 C 又需要调用其他类如 D.E.F 等,假如类 D.E.F 构造很耗时又或者调用很耗时的话是非常不便于测试的(比如是 DAO 类,每次访问数据库都很耗时).所以我们引入 Mock 对象. 如上图,我们将