Los Treasure Valley P3959--

Portal: QAQQAQ

 

Meaning of the questions:

Xiaoming involved in archaeological excavations got a treasure map, treasure map marked on  n- n-th treasure buried in the ground housing, which also gives the  n- n-Treasure a house for development between m m bar roads and their length.

Xiao Ming personally determined to go digging treasure house of all treasures. However, each treasure house is very far from the ground, that is, open up a path to a treasure house from the ground is very difficult, and the road between the treasure house development is relatively much easier.

Xiao Ming's determination moved the sponsor, the sponsor decided to sponsor archaeological excavations free him from the ground to open up a channel of a treasure house, which houses treasures by Xiao Ming leading to a decision.

On this basis, Xiao Ming also need to consider how to cut the road between the treasure house. May have been dug out of the road traffic does not consume any price. Each cut out a new road, Xiao Ming will dig out the treasure by the piece of road can reach the treasure house with the archaeological team. In addition, Xiao Ming did not want to develop useless road, that road between the two have been excavated treasure house no longer develop.

The development of a new road at the cost of:

\mathrm{L} \times \mathrm{K}L×K

L represents the length of this road, on behalf of K to help you get through the treasure house from the sponsor to the number of the treasure house of this road start of treasure house elapsed (including sponsor to help you get through the treasure house and this path starting point treasure House).

Please write programs selected by the sponsors get through the treasures of the house and the road was dug after Xiao Ming, making the total cost of the project a minimum, and outputs the minimum value.

 

Thinking: see the data range, $ n <= 12 $, it is naturally conceivable compressed state.

We use $ dp [i] [mask] $ from $ i $ preservation began to dig, the current state is the minimum cost of $ mask $

Now the difficulty is how to deal with $ K $ - at this point in the depth of the tree.

We use $ dis [i] [mask] $ saved in the current state is $ mask $, and the current best answer, the first $ i $ depth plus one point in the tree (Why plus one? Well look better when transferring ~ ~ ~)

We may worry that the current $ mask $ drawing even the best way to ensure that it can not be extended to the optimal answer to the next node, but considering to be updated $ mask '$, there is always a previous best of $ mask on one side will make even $ current $ mask '$ answer best.

And be updated $ mask '$ must be greater than $ mask $, so every $ dp [i] [mask] $ will be updated to the optimum, then we are in the last update about $ ans $ can be friends ~ ~ ~

 

:( before the code is not saved for every $ mask $ of $ dis $, may lead to an optimal depth map and even point does not correspond to even answer would be too small (see my last 40 minutes Los valleys code that is saved is the minimum depth, not even under optimal depth FIG.))

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10200;
const ll inf=(int)2e9;

ll dp[15][5005],n,m;
ll E[21][21],dis[5005][21];

void checkmin(ll &x,ll y)
{
    if(x>y) x=y;
}

int main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++) E[i][j]=inf;
    }
    int full=(1<<n);
    for(int i=0;i<n;i++)
        for(int j=0;j<full;j++) dp[i][j]=inf;
    for(int i=1;i<=m;i++)
    {
        int x,y; ll z;
        scanf("%d%d%lld",&x,&y,&z);
        x--; y--; if(x==y) continue;
        E[x][y]=min(z,E[x][y]);
        E[y][x]=min(z,E[y][x]);
    }
    for(int start=0;start<n;start++)
    {
        dis[(1<<start)][start]=1; dp[start][(1<<start)]=0;
        for(int mask=0;mask<full;mask++)
        {
            if(!(mask>>start)&1) continue;
            for(int from=0;from<n;from++)
            {
                if(!(mask>>from)&1) continue;
                for(int to=0;to<n;to++)
                {
                    if((mask>>to)&1) continue;
                    if(dp[start][mask]==inf||dis[mask][from]==0) continue;
                    if(E[from][to]==inf) continue;
                    int mask1=mask|(1<<to);
                    if(dp[start][mask1]>dp[start][mask]+dis[mask][from]*E[from][to])
                    {
                        dp[start][mask1]=dp[start][mask]+dis[mask][from]*E[from][to];
                        for(int p=0;p<n;p++) dis[mask1][p]=dis[mask][p];
                        dis[mask1][to]=dis[mask][from]+1;
                    }
                }
            }
        }
    }
    ll ans=inf;
    for(int i=0;i<n;i++) checkmin(ans,dp[i][full-1]);
    cout<<ans<<endl;
    return 0;
}
View Code

(Originally, this practice is wrong, happily built a set of data and found that hack ... but now I can not afford to really understand)

Guess you like

Origin www.cnblogs.com/Forever-666/p/11324537.html