zoukankan      html  css  js  c++  java
  • Codeforces Round #749 (Div. 1 + Div. 2, based on Technocup 2022 Elimination Round 1) F. Defender of Childhood Dreams

    题意

    (n)个点的有向图,点依次编号为(1)(n),若(a<b),则点(a)到点(b)有一条有向边。

    (a,b)之间的路径定义为从(a)出发,按顺序和边的方向走,最终走到(b)点的边集

    彩虹路径定义为路径上的边至少有两种颜色的路径

    问一种给边染色的方案,使得所有长度为(k)的路径都是彩虹路径,并且所用的颜色最少

    (2le k < n le 1000).

    题解

    要求即图中不能存在同色的长为(k)​的链

    考虑把图按点分成(k)块,块与块之间的边用同一种颜色,然后块内的点递归下去做就行.这样能保证同色的链最长是(k-1)

    递归(log_k n)​次,​直到块大小不超过(k)​时,块内的最长链长为(k-1)​,全部染成同一种颜色即可。

    比上一题简单多了

    // Problem: F. Defender of Childhood Dreams
    // Contest: Codeforces - Codeforces Round #749 (Div. 1 + Div. 2, based on Technocup 2022 Elimination Round 1)
    // URL: https://codeforces.com/contest/1586/problem/F
    // Memory Limit: 512 MB
    // Time Limit: 3000 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1007;
    #define ll long long
    int n, m, k, tot, ans;
    int rd() {
    	int s = 0, f = 1; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}
    	return s * f;
    }
    int id[maxn][maxn], col[maxn][maxn];
    
    void link(int l1, int r1, int l2, int r2) {
    	for (int i = l1; i <= r1; i++) {
    		for (int j = l2; j <= r2; j++) {
    			col[i][j] = tot;
    		}
    	}
    }
    
    void sol(int l, int r) {
    	tot++; 	//这一次递归用这一种颜色
    	if (r - l + 1 <= k) {
    		ans = max(ans, tot);
    		for (int i = l; i <= r; i++) {
    			for (int j = l + 1; j <= r; j++) {
    				col[i][j] = tot;
    			}
    		}
    		tot--;
    		return;
    	}
    	int siz = (r - l + k) / k;
    	for (int i = l; i <= r; i += siz) {
    		sol(i, min(r, i + siz - 1));
    		for (int j = i + siz; j <= r; j += siz) {
    			link(i, min(r, i + siz - 1), j, min(r, j + siz - 1));
    		}
    	}
    	tot--;
    }
    int main() {
    	n = rd(), k = rd();
    	for (int i = 1; i <= n; i++) {
    		for (int j = i + 1; j <= n; j++) {
    			id[i][j] = ++tot;
    		}
    	}
    	tot = 0;
    	sol(1, n);
    	printf("%d
    ", ans);
    	for (int i = 1; i <= n; i++) {
    		for (int j = i + 1; j <= n; j++) {
    			printf("%d ", col[i][j]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    http delete 服务端拿不到body
    VUE 指定、获取DOM元素的自定义值
    delphi + redis 实现即时消息
    VUE 父组件、子组件图片链接
    【杂记】Linux 学习笔记
    【杂记】Oracle
    iOS 容易造成循环引用的三种场景
    NSNotificationCenter KVO KVC Delegate Block
    C语言和OC的区别? 面向对象和面向过程的区别?
    SDWebImage的实现原理
  • 原文地址:https://www.cnblogs.com/YjmStr/p/15434049.html
Copyright © 2011-2022 走看看