zoukankan      html  css  js  c++  java
  • CF 1338B Edge Weight Assignment

    传送门

    题目:给定一颗无边权的树,你需要对每条边添加任意大于0的数值。对于树上的任意一条链,对链上的所有边进行(xor)操作后数值为0。你最多和最少可以添加不同的边权。

    思路:

    ①最少:我们可以发现,如果任意两个叶子结点间的边为偶数,则我们只需要用"1"就行。如果出现了偶数,则我们只需要用"1","2","3"就可以,我们用"1","2","3"把奇数条变成偶数条(这),然后其他用"1"填充。

    ②最多:我们可以任意选一个非叶子节点作为根结点,这样就变成了一个有深度的有根树。我们可以知道,一个非叶子节点作为祖先,则它下面的所有边权值(xor)应该都是相同,而且我们可以添加任意的一个数(不限制范围),转为二进制来说,可以是很长的"01"串,这样我们可以有很多组合组成一个相同的数。我们容易知道,如果两个叶子节点距离为2,则他们的权值一定要相同。这样说明除了两个叶子结点距离为2的点,其他点权值都可以不同,然后我们只需要处理一下前面说的特殊情况就行。

      1 #include<iostream>
      2 #include<string>
      3 #include<vector>
      4 #include<cstdio>
      5 #include <stack>
      6 
      7 #define ll long long
      8 #define pb push_back
      9 
     10 using namespace std;
     11 
     12 const int N = 1e5 + 10;
     13 vector<int > E[N];
     14 int du[N], deep[N];
     15 struct node
     16 {
     17     vector<int > son;
     18 }info[N];
     19 
     20 void dfs(int now, int pre)
     21 {
     22     deep[now] = deep[pre] + 1;
     23     for(auto to : E[now]){
     24         if(to == pre) continue;
     25         dfs(to, now);
     26     }
     27 }
     28 
     29 void dfs2(int now, int pre)
     30 {
     31     for(auto to : E[now]){
     32         if(to == pre) continue;
     33         info[now].son.pb(to);
     34         dfs2(to, now);
     35     }
     36 }
     37 
     38 void solve()
     39 {      
     40     int n;
     41     cin >> n;
     42 
     43     int u, v;
     44     for(int i = 1; i < n; ++i){
     45         cin >> u >> v;
     46         E[u].pb(v);
     47         E[v].pb(u);
     48         du[u]++;
     49         du[v]++;
     50     }
     51 
     52     int s = -1;
     53     for(int i = 1; i <= n; ++i){
     54         if(du[i] > 1) continue;
     55         s = i;
     56         break;
     57     }
     58     deep[0] = -1;
     59     dfs(s, 0);
     60     bool even = 1;
     61     for(int i = 1; i <= n; ++i){
     62         if(du[i] > 1) continue;
     63         if(du[i] == 1 && deep[i] % 2 == 0) continue;
     64         even = 0;
     65         break;
     66     }
     67     for(int i = 1; i <= n; ++i){
     68         if(du[i] == 1) continue;
     69         s = i;
     70         break;
     71     }
     72 
     73     dfs2(s, 0);
     74 
     75 
     76     int cnt, sum;
     77     cnt = 0;
     78     for(int i = 1; i <= n; ++i){
     79         if(du[i] == 1) continue;
     80  
     81         if(info[i].son.size() < 2) continue;
     82 
     83         sum = 0;
     84         for(auto he : info[i].son){
     85             if(info[he].son.size()) continue;
     86             sum++;
     87         }
     88         if(sum > 0) cnt += sum - 1;
     89     }
     90     //cout << "ans = ";
     91     cout << (even == 1 ? 1 : 3) << " " << n - 1 - cnt << endl;
     92 }
     93 
     94 int main() {
     95 
     96     ios::sync_with_stdio(false);
     97     cin.tie(0);
     98     cout.tie(0);
     99     solve();
    100     //cout << "ok" << endl;
    101     return 0;
    102 }
  • 相关阅读:
    从原理上理解NodeJS的适用场景
    core 基本操作
    SQL Server 触发器
    Centos 7 Apache .netcore 做转发
    Windows Server 使用 WAMP 并配置 Https
    centos7 apache php git pull
    Visual StudioTools for Unity 使用技巧2
    如何实现Windows Phone代码与Unity相互通信(直接调用)
    关于NGUI与原生2D混用相互遮盖的问题心得
    关于NGUI制作图集在低内存设备上的注意事项
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/13542085.html
Copyright © 2011-2022 走看看