zoukankan      html  css  js  c++  java
  • Codeforces 781C Underground Lab 构造

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

    题目传送门 - CF781C

    题意

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

      $n,mleq 2 imes 10^5, 1leq kleq 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;
    }
    

      

  • 相关阅读:
    VUE中全局变量的定义和使用
    Pull Request 工作流——更高效的管理代码
    仓储repository概念
    Mysql存储过程历史表备份
    OpenStack一键安装
    VMware虚拟机设置Win10固定ip
    C#_NPOI_Excel各种设置
    pycharm修改镜像
    C#模拟POST上传文件帮助类(支持https、http)
    Windows安装RabbitMQ
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/CF781C.html
Copyright © 2011-2022 走看看