2019DX#8

Solved Pro.ID Title Ratio(Accepted / Submitted)
  1001 Acesrc and Cube Hypernet 7.32%(3/41)
  1002 Acesrc and Girlfriend 4.35%(2/46)
  1003 Acesrc and Good Numbers            暴力打表
24.80%(213/859)
  1004 Acesrc and Hunting 21.74%(90/414)
  1005 Acesrc and String Theory 23.46%(38/162)
  1006 Acesrc and Travel                换根树形DP
12.01%(123/1024)
  1007 Andy and Data Structure 0.85%(1/117)
  1008 Andy and Maze                  随机染色+状压DP 15.71%(33/210)
  1009 Calabash and Landlord 18.99%(613/3228)
  1010 Quailty and CCPC 33.48%(1060/3166)
  1011 Roundgod and Milk Tea 17.70%(776/4384)

1006 Acesrc and Travel

换根树形DP

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>
#include <unordered_map>
// #include<bits/extc++.h>
// using namespace __gnu_pbds;
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;

template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}
/**********showtime************/
            const int maxn = 1e5+9;
            int a[maxn],b[maxn];
            vector<int>mp[maxn];
            int n;
            ll dpa[maxn][2], dpb[maxn][2];
            ///dpa[u][0]表示a从u开始选最大所能得,需要从dpb最小的转移过来,实际是个最小值
            ///dpa[u][1] 表示次小值。
            ///dpb[u][0]表示b的,它只能从dpa最大的转移过来,实际上是个最大值。
            ///dpb[u][1]表示次大值

            int sona[maxn], sonb[maxn];
            void dfs1(int u, int fa) {
                dpa[u][0] = dpa[u][1] = inff;
                dpb[u][0] = dpb[u][1] = -inff;
                sona[u] = sonb[u] = 0;
                for(int v : mp[u]) {
                    if(v == fa) continue;
                    dfs1(v, u);
                    if(dpb[v][0] + a[u] - b[u] <= dpa[u][1]) {
                        dpa[u][1] = dpb[v][0] + a[u] - b[u];

                        if(dpa[u][1] < dpa[u][0]) {
                            swap(dpa[u][1] , dpa[u][0]);
                            sona[u] = v;
                        }
                    }
                    if(dpa[v][0] + a[u] - b[u] >= dpb[u][1]) {
                        dpb[u][1] = dpa[v][0] + a[u] - b[u];
                        if(dpb[u][1] > dpb[u][0]) {
                            swap(dpb[u][1], dpb[u][0]);
                            sonb[u] = v;
                        }
                    }
                }
                ///度数为1的节点需要特殊判断,还要区分根节点和叶子节点
                if(mp[u].size() <= 1 && fa != 0) {
                    dpa[u][0] = dpb[u][0] = a[u] - b[u];
                }
            }
            ll ans;
            ll cupa[maxn], cupb[maxn];
            void dfs2(int u, int fa) {

                ll tmp = min(dpa[u][0], cupa[u]);

                if(mp[u].size() == 1 && fa) tmp = cupa[u];
                ans = max(ans, tmp);
                for(int v : mp[u]) {
                    if(v == fa) continue;
                    cupa[v] = max(cupb[u], dpb[u][ sonb[u] == v ? 1: 0]) + a[v] - b[v];
                    cupb[v] = min(cupa[u], dpa[u][ sona[u] == v ? 1: 0]) + a[v] - b[v];
                    dfs2(v, u);
                }
            }
int main(){
            int T;  scanf("%d", &T);
            while(T--) {
                scanf("%d", &n);
                for(int i=1; i<=n; i++) scanf("%d", &a[i]);
                for(int i=1; i<=n; i++) scanf("%d", &b[i]);
                for(int i=1; i<n;  i++) {
                    int u,v;
                    scanf("%d%d", &u, &v);
                    mp[u].pb(v);
                    mp[v].pb(u);
                }

                dfs1(1, 0);
                ans = dpa[1][0];
                if(mp[1].size() == 1) cupa[1] = cupb[1] = a[1] - b[1];
                else cupa[1] = inff, cupb[1] = -inff;

                dfs2(1, 0);
                printf("%lld
", ans);
                for(int i=1; i<=n; i++) mp[i].clear();
            }
            return 0;
}
View Code

1008 Andy and Maze

用到了color coding技巧。

参考和学习

/*
* @Author: chenkexing
* @Date:   2019-08-16 22:30:07
* @Last Modified by:   chenkexing
* @Last Modified time: 2019-08-16 23:30:32
*/
// #pragma GCC optimize(2)
// #pragma GCC optimize(3)
// #pragma GCC optimize(4)
#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <ctime>
#include    <random>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>
// #include<bits/extc++.h>
// using namespace __gnu_pbds;
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<pii, ll> p3;
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;

template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}

/**********showtime************/
            mt19937 rnd(time(0));
            const int maxn = 1e4+9;
            struct E
            {   
                int u,v,w;
            }edge[maxn];
            int col[maxn];
            int n,m,k;
            ll dp[maxn][70];
            ll randgao() {
                for(int i=1; i<=n; i++) col[i] = rnd() % k;

                for(int i=1; i<=n; i++){
                    for(int j=0; j<(1 << k) ; j++) {
                        dp[i][j] = -inff;
                    }
                    int j = (1 << col[i]);
                    dp[i][j] = 0;
                }
                for(int j = 0; j < (1 << k) ; j++ ) {
                    for(int i=1; i<=m; i++) {
                        int u = edge[i].u, v = edge[i].v, w = edge[i].w;
                        if((j & (1 << col[u])))
                            dp[u][j] = max(dp[u][j], dp[v][j ^ (1 << col[u])] + w);
                        if((j & (1 << col[v])))
                            dp[v][j] = max(dp[v][j], dp[u][j ^ (1 << col[v])] + w);
                             
                    }
                }

                int up = (1 << k) - 1;

                ll res = -inff;

                for(int i=1; i<=n; i++) res = max(res, dp[i][up]);

                return res == -inff ? -1 : res;
            }
int main(){
            int T;  scanf("%d", &T);
            while(T--) {
                scanf("%d%d%d", &n, &m, &k);
                for(int i=1; i<=m; i++) {
                    scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
                }
                ll ans = -1;
                for(int rep = 1; rep <= 300; rep++){
                    ans = max(ans, randgao());
                }
                if(ans == -1) puts("impossible");
                else printf("%lld
", ans);
            }

            return 0;
}
View Code
原文地址:https://www.cnblogs.com/ckxkexing/p/11353819.html