F - Negative Traveling Salesman (atcoder.jp)
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <numeric>
#define ll long long
#define PII pair<int, int>
#define TUP tuple<int, int, int>
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1024 * 1024 * 4 + 10;
int d[25][25], dp[1 << 20][20];
void solve() {
/*
2 3
1 2 3
5 5
5 19 10 20 12
5 6
5 19 10 20 12 0
*/
memset(d, 0x3f, sizeof d);
memset(dp, 0x3f, sizeof dp);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
--u, --v;
d[u][v] = w;
}
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (d[i][k] == inf || d[k][j] == inf) continue;
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
}
for (int i = 0; i < n; i++) dp[1 << i][i] = 0;
for (int i = 1; i < (1 << n) - 1; i++) {
for (int j = 0; j < n; j++) {
if ((i >> j & 1) == 0) continue;
if (dp[i][j] == inf) continue;
for (int k = 0; k < n; k++) {
if (i >> k & 1) continue;
if (d[j][k] == inf) continue;
dp[i | 1 << k][k] = min(dp[i | 1 << k][k], dp[i][j] + d[j][k]);
}
}
}
int ans = inf;
for (int i = 0; i < n; i++) {
ans = min(ans, dp[(1 << n) - 1][i]);
}
if (ans == inf) printf("No");
else printf("%d", ans);
return;
}
int main() {
int t = 1;
//scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}