T-net(樹上dp)

 

問題 H: T-net

時間限制: 1 Sec  內存限制: 128 MB
 

題目描述

T-net which is a new telecommunications company, plans to install its base stations in the city. The places where base stations must be installed have been already specified. T-net has two types of antennas to be used in the base stations: (i)antennas with transmission radius a, and (ii) antennas with transmission radius b. Two antennas can communicate with each other if and only if both are inside the coverage area of each other. Antenna with smaller transmission radius of course is cheaper. T-net plans to minimize its cost while keeping the whole network connected. Precisely, T-net plans to
minimize its cost which is the sum of the transmission radii of all antennas. Interestingly, all base-station places are on a line. Help T-net construct a connected network with the minimum cost.

 

輸入

The first line of the input contains three positive integers n, a and b (1 ⩽ n ⩽ 105 and 1 ⩽ a, b ⩽ 105 ) where n is the number of base stations, and a and b are radii as defined in the problem statement. The second line contains n distinct coordinates of base stations on the line with respect to an origin on the line. All coordinates are positive integers not more than 105 .

 

輸出

If it is possible to construct a connected network, print the minimum cost in the output. Otherwise, print -1 .

 

樣例輸入

3 1 3
1 4 3

樣例輸出

7

 

題目給一棵樹,其中一號節點是樹的根。每個節點都有一個字符串,其中葉子節點的字符串組成已給出,給出的字符串有ATCG?五種,其中?代表可以是ATCG中任意一個,所有的字符串和長度均相等。然後父親節點到兒子節點有一個代價矩陣,然後讓所有邊上的代價和最小。

很明顯,字符串中不同位置的字符之間互相沒有影響,所以我們每次考慮一個位置的字符。用dp[i][j]表示第i個點用第j個字母(j是ATCGhash一下所對應的序號)所花費的代價之和,最後對所有的字符取和就行。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e4 + 5;
char str[maxn][205];
int n,k,len;
int s[4][4],l[maxn],m[maxn],mp[200];
ll dp[maxn][4];
bool vis[maxn];
vector <int> vec[maxn];
void dfs(int p, int i)
{
    vis[p] = 1;
    if (m[p])
    {
        int j = m[p];
        if (str[j][i] != '?')
        {
            int k1 = mp[str[j][i]];
            for (int k2 = 0; k2 < 4; ++k2)
                if (k2 != k1)
                    dp[p][k2] = 1e18;
        }
        return;
    }
    for (int a = 0; a < vec[p].size(); ++a)
    {
        int pp = vec[p][a];
        if (vis[pp])
            continue;
        dfs(pp, i);
        for (int kk = 0; kk < 4; ++kk)
        {
            ll minn = 1e18;
            for (int k2 = 0; k2 < 4; ++k2)
                minn = min(minn, dp[pp][k2] + s[kk][k2]);
            dp[p][kk] += minn;
        }
    }
}
int main()
{
    //freopen("in.txt", "r", stdin);
    mp['A'] = 0;
    mp['T'] = 1;
    mp['C'] = 2;
    mp['G'] = 3;
    scanf("%d", &n);
    for (int i = 1; i < n; ++i)
    {
        int u,v;
        scanf("%d%d", &u, &v);
        vec[u].emplace_back(v);
        vec[v].emplace_back(u);
    }
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            scanf("%d", &s[i][j]);
    scanf("%d", &k);
    for (int i = 1; i <= k; ++i)
    {
        scanf("%d %s", &l[i], str[i]);
        m[l[i]] = i;
    }
    len = strlen(str[1]);
    ll ans = 0;
    for (int i = 0; i < len; ++i)
    {
        memset(vis, 0, sizeof vis);
        memset(dp, 0, sizeof dp);
        dfs(1, i);
        ll minn = 1e18;
        for (int j = 0; j < 4; ++j)
            minn = min(minn, dp[1][j]);
        ans += minn;
    }
    printf("%lld\n", ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章