zoukankan      html  css  js  c++  java
  • Codeforces 1103 C. Johnny Solving

    Codeforces 1103 C. Johnny Solving

    题目大意

    有一张 (n) 个点 (m) 条边的简单无向图,每个点的度数至少为 (3) ,你需要构造出两种情况之一

    1. 一条长度至少为 (frac{n}{k}) 的简单路径

    2. (k) 个大小大于 (3) 且不为 (3) 的倍数的简单环,且满足每个环中至少有一个点只属于这个环。

    如果都构造不出来则输出 (-1)

    解题思路

    首先必定可以构造出来,(-1) 就是用来迷惑你的。

    从无向图生成树的角度考虑,如果生成树的最大深度至少为 (frac{n}{k}) ,那么直接输出简单路径,否则可以证明生成树一定有至少 (k+1) 个叶子。

    假设叶子数量小于 (k+1) ,每一个叶子的深度最大为 (frac{n}{k}-1),由于所有叶子到根的路径的并是这棵树,所以所有叶子的深度之和要大于 (n) ,矛盾。

    事实上每一个叶子都可以构造出一个长度不为 (3) 的倍数的简单环,由于每个点度数 $geq 3 $ ,那么每个叶子至少存在两条反祖边,假设叶子 (u) 对应的这两个祖先分别为 (x, y)

    如果其中一个祖先满足 (dep[x] mod 3 eq 0) ,那么 (u) 到这祖先就能形成一个合法环。

    否则两个祖先都满足 (mod 3 = 0) 那么 (x-y) 之间的路径再加上 (u) 就能形成一个 (mod 3 = 1) 的合法环。

    考虑每一个环都包含一个叶子,这个叶子显然满足在所有环里只出现一次。

    code

    /*program by mangoyang*/ 
    #include<bits/stdc++.h>
    #define inf ((ll)(1e17))
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
        int ch = 0, f = 0; x = 0;
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
        for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        if(f) x = -x;
    }
    const int N = 1000005;
    pair<int, int> q[N];
    vector<int> g[N], leaf;
    int vis[N], dep[N], dd[N], ms[N], fa[N], n, m, k;
    inline void dfs(int u){
    	vis[u] = 1, dep[u] = 1; int tot = 0;
    	for(int i = 0; i < (int) g[u].size(); i++){
    		int v = g[u][i];-
    		if(v == fa[u]) continue;
    		if(!vis[v]){
    			fa[v] = u, dd[v] = dd[u] + 1, dfs(v);
    			if(dep[v] >= dep[u]) 
    				dep[u] = dep[v] + 1, ms[u] = v;
    			tot++;
    		}
    		else{
    			if(!q[u].first) q[u].first = v;
    			else if(!q[u].second) q[u].second = v;
    		}
    	}
    	if(!tot) leaf.push_back(u);
    }
    inline void outpath(int u){
    	printf("%d ", u);
    	if(ms[u]) outpath(ms[u]);
    }
    inline void gao(int x, int y){
    	if(dd[x] < dd[y]) swap(x, y);
    	while(x != y) printf("%d ", x), x = fa[x];
    	printf("%d ", y);
    }
    int main(){
    	read(n), read(m), read(k);
    	for(int i = 1, x, y; i <= m; i++){
    		read(x), read(y);
    		g[x].push_back(y), g[y].push_back(x);
    	}
    	dfs(1);
    	if(dep[1] >= n / k){
    		puts("PATH");
    		cout << dep[1] << endl;
    		return outpath(1), 0;
    	}
    	puts("CYCLES");
    	for(int i = 0; i < k; i++){
    		int u = leaf[i];
    		int x = q[u].first, y = q[u].second;
    		if((dd[u] - dd[x] + 1) % 3 != 0) 
                printf("%d
    ", dd[u] - dd[x] + 1), gao(u, x), puts("");
    		else if((dd[u] - dd[y] + 1) % 3 != 0) 
                printf("%d
    ", dd[u] - dd[y] + 1), gao(u, y), puts("");
    		else printf("%d
    ", abs(dd[x] - dd[y]) + 2), gao(x, y), printf("%d
    ", u); 
    	}
    }
    
  • 相关阅读:
    使用math.js进行javascript精确计算
    SpringMVC java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name
    MAC系统下配置环境变量
    javaURL中文乱码的问题
    Mac系统搭建java开发环境
    mysql 删除重复数据保留只保留一条
    SSM 加载配置文件
    CSS3实现元素旋转
    CSS3实现圆角效果
    CSS3 -web-box-shadow实现阴影效果
  • 原文地址:https://www.cnblogs.com/mangoyang/p/10466216.html
Copyright © 2011-2022 走看看