列表

详情


NC20592. [SHOI2015]零件组装机

描述

曾经发明了激光发生器的发明家SHTSC又公开了他的新发明:零件组装机--一种可以生产并组装零件的神秘装置。 
一个零件是一张顶点由0 到n-1标号的无向图,零件组装机由以下两条功能。 
 (1)生产一个仅有一个顶点标号为0而没有边的零件。 
 (2)组合两个已有的零件G1,G2,且G2的顶点数m ≥ G1的顶点数n,得到新的零件G。G的顶点集合是G1、G2顶点集合的并 集,并且G2的顶点i(0 ≤ i < m)被重新标号为n+i。G的边集是G1、G2边集的并集再对所有标号为a(a ≥ n)的顶点添加一 条连接(a,a mod n)的无向边。
   
现在SHTSC正在思考,对于一个给定的零件,能否由零件组装机生产组装得到。注意:零件是带标号的,这意味着 两个零件即使仅有标号不同也被视为不同的零件。为了帮助你理解问题,SHTSC特地给了你顶点数 ≤ 5的零件的图例。 

输入描述

第一行一个整数t,表示有t组数据。 每组数据的第一行两个整数n,m。表示某个带标号的无向图有n个顶点0到n-1标号,m是边的数量。
接下来m行,每行两个整数u,v表示一条从u到v的无向边。
t ≤ 10,n,m ≤ 100000,0 ≤ u, v < n

输出描述

对于每组数据,输出一行。如果这个无向图可以被零件制造机制造输出"YES"否则输出"NO"。

示例1

输入:

2
1 0
2 0

输出:

YES
NO

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 353ms, 内存消耗: 1632K, 提交时间: 2019-03-16 12:59:33

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
 
const int maxn = 1E5 + 10;
 
struct E{
	int x,y;
	E(){}
	E(int x,int y): x(x),y(y){}
	bool operator < (const E &b) const {return x < b.x;}
}e[maxn];
 
int t,L[maxn];
bool bo[maxn];
 
bool Judge(int n,int l,int r)
{
	if (n == 1) return l == r;
	if (l == r) return 0;
	for (int i = 0; i < n; i++) 
		L[i] = maxn,bo[i] = 0;
	for (int i = l; i < r; i++) {
		int x = e[i].x;
		int y = e[i].y;
		if (x == L[y]) return 0;
		L[y] = min(L[y],x);
	}
	for (int i = 0; i < n; i++) 
		if (L[i] == 0) bo[i] = 1;
		else if (L[i] - L[i-1] == 1 && bo[i-1]) bo[i] = 1;
	int flag = 0,siz;
	for (int i = 0; i < n/2; i++) {
		siz = i + 1;
		bool ok = 1;
		for (int j = i + siz; j < n; j += siz) {
			if (bo[j] && L[j] == i) continue;
			ok = 0;	break;
		}
		if (ok) {flag = 1; break;}
	}
	if (!flag) return 0;
	int p1 = l,p2;
	for (int i = l; i < r; i++) {
		int x = e[i].x;
		int y = e[i].y;
		if (x == siz) break;
		if (y < siz) e[p1++] = e[i];
	}
	p2 = p1;
	for (int i = l; i < r; i++) {
		int x = e[i].x;
		int y = e[i].y;
		if (x < siz) continue;
		e[p2++] = E(e[i].x - siz,e[i].y - siz);
	}
	return Judge(siz,l,p1) && Judge(n - siz,p1,p2);
}
 
int getint()
{
	char ch = getchar();
	int ret = 0;
	while (ch < '0' || '9' < ch) ch = getchar();
	while ('0' <= ch && ch <= '9')
		ret = ret*10 + ch - '0',ch = getchar();
	return ret;
}
 
int main()
{
	#ifdef DMC
		freopen("DMC.txt","r",stdin);
	#endif
	
	t = getint();
	while (t--) {
		int n,m;
		n = getint();
		m = getint();
		for (int i = 0; i < m; i++) {
			int x = getint();
			int y = getint();
			e[i] = E(min(x,y),max(x,y));
		} 
		sort(e,e + m);
		if (Judge(n,0,m)) puts("YES");
		else puts("NO");
	}
	return 0;
}

上一题