//Illustration Attached. -KrisXJ 8-3
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=15;
const ll INF=1145141919810007210;
int n,m;
ll G[MAXN+1][MAXN+1];
int main()
{
cin>>n>>m;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
G[i][j]=(i == j) ? 0 : INF;
for(int i = 0;i < m;i++)
{
int u,v,w;
cin>>u>>v>>w;
if(w<G[u][v])
{
G[u][v] = w;
G[v][u] = w;
}
}
ll ans = INF;
int full_mask = (1 << n) - 1;
for(int begin = 1;begin <= n;begin++)
{
vector<ll> dp(1<<n,INF); // dp[mask]:当前已开发宝藏屋为mask时的最小代价
vector<vector<int> > depth(1 << n,vector<int>(n + 1,INF));// depth[mask][u]:mask状态下u的深度
int init = 1 << (begin-1);
dp[init] = 0;
depth[init][begin] = 1;
for(int mask = init;mask < (1 << n);mask++)
{
if(dp[mask] == INF) //这个状态还没有算过
continue;
for(int u = 1;u <= n;u++)
{
if(!(mask& (1 << (u - 1)))) //u不在当前掩码中
continue;
int d = depth[mask][u];
if(d == INF)
continue;
for(int v = 1;v<=n;v++)
{
if(u == v)
continue;
if(mask & (1 << (v - 1)))
continue;
if(G[u][v] == INF)
continue;
//排除:同一节点、v已处理、不存在边
int new_mask=mask | (1 << (v - 1));
ll new_cost = dp[mask] + G[u][v] * d;
int new_depth = d+1;
if(new_cost < dp[new_mask])
{
dp[new_mask] = new_cost;
for(int w =1;w <= n;w++)
depth[new_mask][w] = depth[mask][w];
depth[new_mask][v] = new_depth;
}
else if(new_cost == dp[new_mask] && new_depth < depth[new_mask][v])
depth[new_mask][v] = new_depth;
}
}
}
if(dp[full_mask] < ans)
ans = dp[full_mask];
}
cout<<ans;
return 0;
}
我在一开始使用了上述代码提交,发现只有 Subtask 2
的20个测试点通过。部分思路已注释出。代码的问题在哪里呢?