Codeforces 781C Underground Lab 构造

原文链接https://www.cnblogs.com/zhouzhendong/p/CF781C.html

题目传送门 - CF781C

题意

  给定一个 n 个点 m 条边的无向连通图,请你用 k 条长度不大于 $\lceil 2n/k \rceil$ 的路径来覆盖所有节点至少一次。每一条路径长度至少为 1 ,同一条路径可以多次经过同一个节点。

  $n,m\leq 2\times 10^5,\ \ 1\leq k\leq n$

题解

  连通图是一个很优秀的性质。

  我们只需要找出这个图的任意一个 dfs 生成树,并求出其欧拉序。由于欧拉序可以表示成一条长度为 2n-1 的连续路径,所以我们只需要把他分成 k 段就好了。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL read(){
	LL x=0,f=1;
	char ch=getchar();
	while (!isdigit(ch)&&ch!=‘-‘)
		ch=getchar();
	if (ch==‘-‘)
		f=-1,ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x*f;
}
const int N=400005;
int n,m,k;
vector <int> e[N];
int vis[N];
int dfn[N],b[N],t=0;
void dfs(int x){
	dfn[++t]=x;
	vis[x]=1;
	for (auto y : e[x])
		if (!vis[y]){
			dfs(y);
			dfn[++t]=x;
		}
}
int main(){
	n=read(),m=read(),k=read();
	for (int i=1;i<=m;i++){
		int a=read(),b=read();
		e[a].push_back(b);
		e[b].push_back(a);
	}
	memset(vis,0,sizeof vis);
	dfs(1);
	int s=(2*n+k-1)/k;
	memset(b,0,sizeof b);
	b[t]=1;
	for (int i=1;i<k;i++)
		b[i]=1;
	for (int i=k-1,last=t;i>=1;i--){
		if (last-i>s)
			swap(b[i],b[last-s]),last=last-s;
		else
			last=i;
	}
	for (int last=1,i=1;i<=t;i++)
		if (b[i]){
			printf("%d ",i-last+1);
			for (int j=last;j<=i;j++)
				printf("%d ",dfn[j]);
			puts("");
			last=i+1;
		}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/CF781C.html

时间: 2024-08-06 00:58:15

Codeforces 781C Underground Lab 构造的相关文章

Codeforces 534C Polycarpus&#39; Dice 构造

题意:给你n个筛子,第 i 个筛子有 可以表示范围 1-a[i]的数,给你最后筛子和,问你每个筛子不可能的值有多少个. 解题思路:得到每个筛子的取值范围. 解题代码: 1 // File Name: c.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月13日 星期一 00时38分58秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #includ

Codeforces 432E Square Tiling(构造+贪心)

我们通常这么写 using (SqlDataReader drm = sqlComm.ExecuteReader()) { drm.Read();//以下把数据库中读出的Image流在图片框中显示出来. MemoryStream ms = new MemoryStream((byte[])drm["Logo"]); Image img = Image.FromStream(ms); this.pictureBox1.Image = img; } 我的写数据 private void b

Underground Lab CodeForces - 782E (欧拉序)

大意:$n$结点,$m$条边无向图, 有$k$个人, 每个人最多走$\left\lceil\frac {2n}{k}\right\rceil$步, 求一种方案使得$k$个人走遍所有的点 $n$结点树的欧拉序长度为$2n-1$, 直接取$dfs$树的欧拉序即可 #include <iostream> #include <algorithm> #include <math.h> #include <cstdio> #include <vector>

Codeforces 482A Diverse Permutation(构造)

题目链接:Codeforces 482A Diverse Permutation 题目大意:给定N和K,即有一个1~N的序列,现在要求找到一个排序,使得说所有的|pi?pi+1|的值有确定K种不同. 解题思路:构造,1,K+1,2,K,3,K-1,... K+2,K+3 ... N. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn

CodeForces 404C Restore Graph (构造)

题意:让人构造一个图,满足每个结点边的数目不超过 k,然后给出每个结点到某个结点的最短距离. 析:很容易看出来如果可能的话,树是一定满足条件的,只要从头开始构造这棵树就好,中途超了int...找了好久. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include

codeforces #550D Regular Bridge 构造

题目大意:给定k(1≤k≤100),要求构造一张简单无向连通图,使得存在一个桥,且每一个点的度数都为k k为偶数时无解 证明: 将这个图缩边双,能够得到一棵树 那么一定存在一个叶节点,仅仅连接一条桥边 那么这个边双内部全部点度数之和为偶数 除掉连出去的桥边外度数之和为奇数 故不合法 然后k为奇数的时候我们仅仅须要构造两个对称的边双被一条桥边连接的图即可了 因为每一个点度数为k.因此每一边至少须要k+1个点 可是k+1个点奇偶性不合法.因此每一边至少须要k+2个点 如今问题转化成了给定一个度数数组

Codeforces 482B Interesting Array 构造+线段树判可行

题目链接:点击打开链接 题意: 构造一个n长的序列,m个限制: 每个限制[l, r] q 序列要满足 区间[l,r]的所有数 & 起来结果是q 思路: 直接构造,然后判可行就好了.. #include <stdio.h> #include <cstring> #include <iostream> #include <map> template <class T> inline bool rd(T &ret) { char c;

Codeforces 468A 24 Game(构造)

题目链接:Codeforces 468A 24 Game 题目大意:给出n,表示有1~n这n个数,判断能否进n-1次操作获得24. 解题思路:4,5的情况可以手动处理出来,然后对于大于4,5的情况可以通过两两相减,形成若干个1. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int main () { int n; scanf("%d",

Codeforces 482 - Diverse Permutation 构造题

这是一道蛮基础的构造题. - k         +(k - 1)      -(k - 2) 1 + k ,    1 ,         k ,             2,    ................... \  /        \  /           \  / k          k-1          k-2 如图所示,先构造第一个数,就是1 + k, 然后接下来每个数字和上个数相差k , k -1 , k -2 这样下来,最后一个数字就是一个中间的数字,过程就