CF830E题解

博客探讨了一种图论问题,涉及环、树形和菊花形结构的边权优化。文章通过分析样例,揭示了解决这类问题的关键策略,包括环直接填充111,菊花形结构中间填222周围填111,以及针对树和特殊链状结构的解法。作者通过数学推导和链的贡献最大化,确定了节点值的分布方式,并提供了C++代码实现。

CF830E

题目已经很简洁了,我们考虑对于样例进行分析。

  • 首先不用脑子就能想到的就是环的情况,有环直接全部填 1 1 1 就好了。

我指的是环所在的连通块。

  • 之后研究样例发现对于树的情况也是有解的,然后我们会想到菊花的情况,对于菊花,也就是 ∃ i , d e g i ≥ 4 \exist i, deg_i \ge 4 i,degi4 就是有解的,中间填 2 2 2,周围填 1 1 1
  • 我们发现 ∀ i , d e g i ≤ 2 \forall i, deg_i \le 2 i,degi2 是无解的。
  • 然后我们发现只有一个 d e g i = 3 deg_i = 3 degi=3 的情况不好算,我们先看两个的情况。也就是有两个度数为 3 3 3 的点连在一起了,我们直接对于两个点赋值 2 2 2,其他为 1 1 1 即可。

一开始我是想着两条链之间的点赋值 2 2 2,后面发现 1 1 1 也是可以的,这样就很简洁了。


然后我们开始讨论只有一个 d e g i = 3 deg_i = 3 degi=3 的情况。
本质上就是一个点,三条链的情况
fM23Ae.png
发现我们可以对于每一条链进行单独考虑。我们不妨设这样一条链从头到尾是 a 1 ∼ a n a_1 \sim a_n a1an 其中 a 1 a_1 a1 是图中的 1 1 1 号节点。
之后我们考虑使这个贡献最大,也就是使这个函数最大。
− ∑ i = 1 n − 1 a i a i + 1 + ∑ i = 1 n a i 2 - \sum_{i = 1} ^ {n - 1} a_i a_{i + 1} + \sum_{i = 1} ^ n a_i ^ 2 i=1n1aiai+1+i=1nai2
然后经典 × 2 \times 2 ×2
∑ i = 1 n − 1 ( a i + 1 − a i ) 2 + a 1 2 + a n 2 2 \dfrac{ \sum_{i = 1} ^ {n - 1} (a_{i + 1} - a_i) ^ 2 + a_1 ^ 2 + a_n ^ 2} {2} 2i=1n1(ai+1ai)2+a12+an2
然后要让后面的最大,可以用偏微分,然后找找规律得到 a i ≡ 1 n a_i \equiv \frac{1}{n} ain1

这里本质上是将每个 a i a_i ai 看成实数,之后同时乘以 n n n。然后每一个 a i a_i ai 都是一个 n − i n \frac{n - i}{n} nni 的形式。
我们要看什么时候这个东西合法,不妨设 d i = a i − a i − 1 , d 1 = a 1 d_i = a_{i} - a_{i -1}, d_1 = a_1 di=aiai1,d1=a1 那么 ∑ i = 1 n d i = a n = S \sum_{i = 1} ^ {n} d_i = a_n = S i=1ndi=an=S。然后 CF 上说最好的选择是 a i ≡ S n a_i \equiv \frac{S}{n} ainS,很好理解就是和固定,每一个数肯定是使其相差要尽量大,就选 a i = S i n a_i = \frac{Si}{n} ai=nSi,然后我们考虑反一下这个,因为 a 1 a_1 a1 会用到很多次。

然后对于每一条链的赋值我们除了找规律还有另一种方法。

我承认我看不懂 CF 题解。

直接对于每一个数进行一次偏微分,然后发现只有一个数其进行偏微分之后存在常数项,然后发现每一个数都是 n − i n \frac{n - i}{n} nni

我们来算一下一条链的贡献。
设三条链分别是 A , B , C A, B, C A,B,C
然后为了方便我们让 a n a_n an 作为 1 1 1 号点。

我们设 S S S 1 1 1 号节点的值。

2 A = ∑ i = 1 n d i 2 + S 2 , . ∑ i = 1 n d i = S , 2A = \sum_{i = 1} ^ n d_i^2 + S ^ 2,. \sum_{i = 1} ^ n d_i = S, 2A=i=1ndi2+S2,.i=1ndi=S,

2 A − S 2 = S 2 p 2A - S^2 = \frac{S^2}{p} 2AS2=pS2

之后我们需要解方程,也就是要保证贡献是负的,我们开始为了方便变号了。不妨考虑设全图的贡献是 2 D 2D 2D, − 2 D + S 2 = ( 2 A − S 2 ) + ( 2 B − S 2 ) + ( 2 C − S 2 ) - 2D + S^2 = (2A - S^2) +(2B - S^2)+ (2C - S^2) 2D+S2=(2AS2)+(2BS2)+(2CS2)。长度分别为 p , q , z p, q, z p,q,z

全图贡献也是正的。

之后可以得到 − 2 D + S 2 = ( 2 A − S 2 ) + ( 2 B − S 2 ) + ( 2 C − S 2 ) = ( S 2 p + S 2 q + S 2 z ) - 2D + S^2 = (2A - S^2) +(2B - S^2)+ (2C - S^2) = (\frac{S^2}{p} + \frac{S^2}{q} + \frac{S^2}{z}) 2D+S2=(2AS2)+(2BS2)+(2CS2)=(pS2+qS2+zS2)

之后可以解得 − 2 D = S 2 × ( 1 p + 1 q + 1 z − 1 ) - 2D = S^2\times (\frac{1}{p} + \frac{1}{q} + \frac{1}{z} - 1) 2D=S2×(p1+q1+z11)

然后要让 − 2 D ≤ 0 -2D \le 0 2D0 也就是合法的,就要 1 p + 1 + 1 q + 1 + 1 z + 1 ≤ 1 \frac{1}{p + 1} + \frac{1}{q + 1} + \frac{1}{z + 1} \le 1 p+11+q+11+z+111

就是右边要小于 0 0 0

#include <bits/stdc++.h>
using namespace std;

//#define Fread
// #define Getmod

#ifdef Fread
char buf[1 << 21], *iS, *iT;
#define gc() (iS == iT ? (iT = (iS = buf) + fread (buf, 1, 1 << 21, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
#endif // Fread

template <typename T>
void r1(T &x) {
	x = 0;
	char c(getchar());
	int f(1);
	for(; c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
	for(; '0' <= c && c <= '9';c = getchar()) x = (x * 10) + (c ^ 48);
	x *= f;
}

const int mod  = 1e9 + 7;
#ifdef Getmod
template <int mod>
struct typemod {
    int z;
    typemod(int a = 0) : z(a) {}
    inline int inc(int a,int b) const {return a += b - mod, a + ((a >> 31) & mod);}
    inline int dec(int a,int b) const {return a -= b, a + ((a >> 31) & mod);}
    inline int mul(int a,int b) const {return 1ll * a * b % mod;}
    typemod<mod> operator + (const typemod<mod> &x) const {return typemod(inc(z, x.z));}
    typemod<mod> operator - (const typemod<mod> &x) const {return typemod(dec(z, x.z));}
    typemod<mod> operator * (const typemod<mod> &x) const {return typemod(mul(z, x.z));}
    typemod<mod>& operator += (const typemod<mod> &x) {*this = *this + x; return *this;}
    typemod<mod>& operator -= (const typemod<mod> &x) {*this = *this - x; return *this;}
    typemod<mod>& operator *= (const typemod<mod> &x) {*this = *this * x; return *this;}
    int operator == (const typemod<mod> &x) const {return x.z == z;}
    int operator != (const typemod<mod> &x) const {return x.z != z;}
};
typedef typemod<mod> Tm;
#endif
template <typename T,typename... Args> inline void r1(T& t, Args&... args) {
    r1(t);  r1(args...);
}

// #define int long long
const int maxn = 2e5 + 5;
vector<int> vc[3];
int head[maxn], cnt;
int n, m;
int deg[maxn];
struct Edge {
    int to, next;
}edg[maxn << 1];

void add(int u,int v) {
    edg[++ cnt] = (Edge) {v, head[u]}, head[u] = cnt, ++ deg[v];
}
int vis[maxn], col[maxn];

void dfs(int p,int pre) {
    vis[p] = 0;
    if(!col[p]) col[p] = 1;
    for(int i = head[p];i;i = edg[i].next) {
        int to = edg[i].to; if(to == pre) continue;
        if(vis[to]) dfs(to, p);
    }
}

int getCir(int p,int pre) {
    vis[p] = 1;
    for(int i = head[p];i;i = edg[i].next) {
        int to = edg[i].to; if(to == pre) continue;
        if(vis[to]) return 1;
        if(getCir(to, p)) return 1;
    }
    return 0;
}

int getdeg(int p,int pre) {
    if(pre && deg[p] == 3) return col[p] = 2, 1;
    for(int i = head[p];i;i = edg[i].next) {
        int to = edg[i].to; if(to == pre) continue;
        if(getdeg(to, p)) return col[p] = 2, 1;
    }
    return 0;
}

void getline(int p,int pre,int opt) {
    vc[opt].push_back(p);
    for(int i = head[p];i;i = edg[i].next) {
        int to = edg[i].to; if(to == pre) continue;
        getline(to, p, opt);
    }
}

bool cmp(const vector<int> & a, const vector<int> &b) {
    return a.size() < b.size();
}

#define Online
signed main() {
#ifndef Online
    freopen("S.in", "r", stdin);
    freopen("S.out", "w", stdout);
#endif

    auto Print = [&](int opt) {
        if(opt == 0) return puts("NO"), void();
        puts("YES");
        for(int i = 1; i <= n; ++ i) printf("%d%c", col[i], " \n"[i == n]);
        return ;
    };

    auto WorK = [&] () {
        int i, j, flag(0);
        r1(n, m);
        for(i = 0; i < 3; ++ i) vc[i].clear();
        for(i = 1; i <= n; ++ i) vis[i] = head[i] = col[i] = deg[i] = 0; cnt = 0;
        for(i = 1; i <= m; ++ i) {
            int u, v;
            r1(u, v);
            add(u, v), add(v, u);
        }
        for(i = 1; !flag && i <= n; ++ i) if(!vis[i]) {
            if((flag = getCir(i, 0)))  dfs(i, 0);
        }
//        puts("ZZZ");
        for(i = 1; !flag && i <= n; ++ i) if(deg[i] > 3) {
            flag = 1; col[i] = 2, dfs(i, 0);
        }
        for(i = 1; !flag && i <= n; ++ i) if(deg[i] == 3) {
            if((flag = getdeg(i, 0))) {
                col[i] = 2;
                dfs(i, 0);
//                puts("ZZZ");
            }
        }
        for(i = 1; !flag && i <= n; ++ i) if(deg[i] == 3) {
            int tot(0);
            for(int x = 0; x < 3; ++ x) vc[x].clear();
            for(int j = head[i];j;j = edg[j].next) {
                int to = edg[j].to;
                getline(to, i, tot ++);
            }
            sort(vc, vc + 3, cmp);
            if(vc[1].size() == 1 || (vc[1].size() == 2 && vc[0].size() == 1 && vc[2].size() < 5)) continue;
            flag = 1;
            if(vc[2].size() >= 5) {
                col[i] = 6;
                col[vc[0][0]] = 3, col[vc[1][0]] = 4;
                col[vc[1][1]] = 2;
                for(j = 0; j < 5; ++ j) col[vc[2][j]] = 5 - j;
            }
            else {
                col[i] = (vc[0].size() + 1) * (vc[1].size() + 1) * (vc[2].size() + 1);
                for(j = 0; j < 3; ++ j) for(int k = 0; k < vc[j].size(); ++ k)
                    col[vc[j][k]] = col[i] / (vc[j].size() + 1) * (vc[j].size() - k);
            }
        }
        Print(flag);
    };

    int T;
    r1(T);
    while(T --) WorK();
	return 0;
}
/*
3
4 4
1 2
2 3
3 4
1 4

5 4
1 2
1 3
1 4
1 5

9 7
1 3
1 5
2 6
2 7
1 9
9 4
4 2



*/

内容概要:本文系统介绍了标准化和软件知识产权的基础知识,涵盖标准化的基本概念、分类、标准代号、国际标准的采用原则及程度,重点讲解了信息技术标准化、ISO与IEC等国际标准化组织以及ISO9000和ISO/IEC15504等重要标准体系;在知识产权部分,详细阐述了知识产权的定义、分类及特点,重点分析了计算机软件著作权的主体、客体、权利内容、行使方式、保护期限及侵权认定,同时涉及商业秘密的构成与侵权形式、专利权的类型与申请条件,以及企业如何综合运用著作权、专利、商标和商业秘密等方式保护软件知识产权。; 适合人群:从事软件开发、项目管理、IT标准化或知识产权相关工作的技术人员与管理人员,以及备考相关资格考试的学习者;具备一定信息技术背景,希望系统掌握标准化与软件知识产权基础知识的专业人员。; 使用场景及目标:①帮助理解各类标准的分类体系及国际标准采用方式,提升标准化实践能力;②指导企业在软件研发过程中有效保护知识产权,规避法律风险;③为软件著作权登记、专利申请、技术保密等提供理论依据和操作指引。; 阅读建议:建议结合国家相关政策法规和实际案例进行深入学习,重点关注软件著作权与专利权的适用边界、标准制定流程及企业知识产权管理策略,强化理论与实践的结合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值