题解-AtCoder ARC-078F Mole and Abandoned Mine

problem

ATC-arc078F

Summary meaning of problems: Given a \ (n-\) point \ (m \) edge simple undirected graph (no re-Loop-free side), while the cost has now cut a number of sides, such that the \ (1 \) the \ (n-\) and only a simple path, seeking to minimize costs.

\ (N \ 15, n-1 \ m \ the \ binom n2 \)

Solution

See \ (n \ leq 15 \) probably can guess complexity is \ (O (3 ^ n) \) or so, then think straight Steiner tree with a quick solution, to no avail.

The situation began to ponder the final situation, there must be a \ (1 \) to \ (n \) path, and can not exist other paths connecting two points on this path. In other words, each starting from the point and then just walk the path of non-sides can only reach a point on the path.

Consider the original question requires a minimum of border erase expenses, correspond to the above approach is easy to think of the right side to convert to maximize stay and

The picture came out, probably to say at each point on the path nod are hung several sets, and due to be maximized are reserved than the right side and so all sides within each collection.

Then it is easy to get a dp: set \ (f [i] [S ] \) represents the path (final connection \ (1 \) and \ (n-\) path) went to the \ (I \) , and set \ (S \) point in the already hung in the front, then there are two transfers:

  • Further on the path: \ (F [I] [S] \ rightarrow F [J] [S \ Cup \ {J \}] \) , increase the weight of the connection is \ (i, j \) in the right side
  • Hanging a set point current: \ (F [I] [S] \ rightarrow F [I] [S \ Cup T] \) , the right to increase the set value \ (T \) side and the right side of all

As long as a pre-treatment \ (g [S] \) represents a set of \ (S \) side and the right, this step can seek violence, the complexity of the \ (O (2 ^ nn ^ 2) \)

And then transferred, when the need to enumerate the subset of transfer (for Global, the complement of the enumerated subset and a subset of the enumerated complexity equivalent), the complexity of the \ (O (n3 ^ n) \)

Overall complexity \ (O (2 ^ nn ^ 2 + n3 ^ n) \)

Code

#include <cstdio>

#define bin(x) (1<<(x))
#define b(x) (1<<(x)>>1)

inline void cmax(int&x, const int y) {x < y && (x = y);}

const int N = 17, M = 40100;
int f[N][M], g[M];
int mp[N][N];
int n, m;

int main() {
    scanf("%d%d",&n,&m); int Ans = 0;
    for(int i=1,x,y,z;i<=m;++i) {
        scanf("%d%d%d",&x,&y,&z), Ans += z;
        mp[x][y] = mp[y][x] = z;
    }
    for(int s=0;s<bin(n);++s) {
        int&v = g[s];
        for(int i=1;i<=n;++i) if(s & b(i)) 
        for(int j=i+1;j<=n;++j) if(s & b(j)) v += mp[i][j];
    }
    for(int i=1;i<=n;++i)
    for(int j=0;j<bin(n);++j)
        f[i][j] = -1;
    
    f[1][1] = 0;
    for(int S=1;S<bin(n);++S)
    for(int i=1;i<=n;++i) if((S & b(i)) and ~f[i][S]) {
        for(int j=1;j<=n;++j) if((~S & b(j)) and mp[i][j]) cmax(f[j][S|b(j)], f[i][S] + mp[i][j]);
        for(int iS=(bin(n)-1)^S, s = iS; s; s = (s-1) & iS)
            cmax(f[i][S|s], f[i][S] + g[s|b(i)]);
    }
    printf("%d\n", Ans - f[n][bin(n)-1]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/penth/p/11368096.html