Codeforces Round #592 (Div. 2)

D. Paint the Tree

题意:
给出一棵树,有三种颜色,要求任意链上的三点的颜色是不一样的,每个点图3种颜色都有自己的花费值,问最小的花费
Solution:
显然一个点度超过2,那么这3个点颜色都不同,无解
所以度都为1,2。树退化成链。
确定了第1,2个,第3个点也唯一确定了(不和1,2的一样),那第4个也出来了
所以两个点就能确定所有点。枚举前两个点颜色就行

/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>

typedef long long LL;
typedef unsigned long long ULL;
using namespace std;

bool Sqrt(LL n) { return (LL)sqrt(n) * sqrt(n) == n; }
const double PI = acos(-1.0), ESP = 1e-10;
const LL INF = 99999999999999;
const int inf = 999999999, N = 1e5 + 5;
int n, u, v, rt, a[] = {1, 2, 3}, ans[N], cur[N], c[4][N], deg[N];
LL res = 1e18, cost;
vector<int> G[N];

void dfs(int u, int h, int p = 0)
{
    cost += c[a[h]][u];
    cur[u] = h;
    for(auto v : G[u]) if(v != p)
        dfs(v, (h + 1) % 3, u);
}

void solve()
{
    cost = 0;
    dfs(rt, 0);
    if(cost < res) {
        res = cost;
        for(int i = 1; i <= n; i++) ans[i] = a[cur[i]];
    }
}

int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    scanf("%d", &n);
    for(int i = 1; i <= 3; i++) for(int j = 1; j <= n; j++) scanf("%d", &c[i][j]);
    for(int i = 1; i < n; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v); G[v].push_back(u);
        deg[v]++; deg[u]++;
    }
    rt = -1;
    for(int i = 1; i <= n; i++) {
        if(deg[i] > 2) { puts("-1"); exit(0);}
        if(deg[i] == 1 && rt == -1) rt=  i;
    }
    do {
        solve();
    }while(next_permutation(a, a + 3));
    printf("%lld\n", res);
    for(int i = 1; i < n; i++) printf("%d ", ans[i]);
    printf("%d\n", ans[n]);

    return 0;
}
/*
    input:
    output:
    modeling:
    methods:
    complexity:
    summary:
*/

C. The Football Season
简单数学,打的时候没有发现限制条件x < w,T了;后来狂想exgcd,emmmmm

LL n, p, w, d;

int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    while(scanf("%lld%lld%lld%lld", &n, &p, &w, &d) == 4) {
        bool flag = 1;
        for(LL x = 0, y; x < w; x++) {
            LL k = p - d * x;
            if(k % w == 0) {
                y = k / w;
                if(y >= 0 && x + y <= n) { flag = 0; printf("%lld %lld %lld\n", y, x, n - x - y); break;}
            }
        }
        if(flag) puts("-1");
    }

    return 0;
}

原文地址:https://www.cnblogs.com/000what/p/11674057.html

时间: 2024-10-12 11:39:57

Codeforces Round #592 (Div. 2)的相关文章

Codeforces Round #592 (Div. 2) CF1244A Pens and Pencils题解

题目链接 入门题,求\(\lceil\frac{a}{c}\rceil\)与\(\lceil\frac{b}{d}\rceil\),判断和是否大于\(k\),大于输出\(-1\),小于等于则输出两数.唯一要注意的一点就是\(double\)与\(int\)类型之间的转换. #include<cstdio> #include<cmath> int a,t,b,c,d,k,ans; int main(){ scanf("%d",&t); while(t--)

Codeforces Round #592 (Div. 2) C - The Football Season(推公式)

?? ?? ?? 题意加题解: //x*w+y*d=p; //x+y+z=0 int main() { ll n,p,w,d; cin>>n>>p>>w>>d; ll y=0; while(y<w&&(p-d*y)%w) ++y; if(y==w) return puts("-1"),0; ll x=(p-d*y)/w; if(x<0||x+y>n) return puts("-1")

Codeforces Round #592 (Div. 2) E

给你一个数组,你最多可以进行k次操作,每次操作可以使一个数+1或者-1,问操作之后数组的极差最小可能是多少 利用map来模拟移动,可以观察到每次应该选择数量少的一组数让他们进行移动是最优的 int main(){ int n; ll k; cin >> n >> k; vector<int> a(n); map<int,int> ls; for(int i = 0 ; i < n ; i++) cin >> a[i],ls[a[i]]++;

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除

Codeforces Round #339 (Div. 2) B. Gena&#39;s Code

B. Gena's Code It's the year 4527 and the tanks game that we all know and love still exists. There also exists Great Gena's code, written in 2016. The problem this code solves is: given the number of tanks that go into the battle from each country, f