Pagini recente » Monitorul de evaluare | Cod sursa (job #3321974) | Diferente pentru concursuri intre reviziile 182 si 166 | Cod sursa (job #3336556) | Cod sursa (job #3351118)
#include <bits/stdc++.h>
using namespace std;
const int max_size = 65, INF = 1e9 + 2;
struct str {
int nod, cost;
bool operator < (const str &aux) const
{
return cost > aux.cost;
}
};
vector <pair <int, int>> mc[max_size], flowedge[max_size];
int indeg[max_size], outdeg[max_size], dist[max_size][max_size], cap[max_size][max_size], d[max_size], aux[max_size], t[max_size], pr[max_size], n;
priority_queue <str> pq;
void bf ()
{
for (int i = 1; i <= 2 + n; i++)
{
aux[i] = INF;
}
queue <int> q;
q.push(1);
aux[1] = 0;
while (!q.empty())
{
int nod = q.front();
q.pop();
d[nod] = 0;
for (auto f : flowedge[nod])
{
if (cap[nod][f.first] > 0 && aux[nod] + f.second < aux[f.first])
{
aux[f.first] = aux[nod] + f.second;
if (d[f.first] == 0)
{
q.push(f.first);
d[f.first] = 1;
}
}
}
}
}
bool djk ()
{
for (int i = 1; i <= 2 + n; i++)
{
d[i] = INF;
pr[i] = INF;
t[i] = 0;
}
d[1] = 0;
pr[1] = 0;
pq.push({1, 0});
while (!pq.empty())
{
int nod = pq.top().nod, val = pq.top().cost;
pq.pop();
if (d[nod] < val)
{
continue;
}
for (auto f : flowedge[nod])
{
if (cap[nod][f.first] > 0 && d[nod] + f.second + aux[nod] - aux[f.first] < d[f.first])
{
d[f.first] = d[nod] + f.second + aux[nod] - aux[f.first];
pr[f.first] = pr[nod] + f.second;
t[f.first] = nod;
pq.push({f.first, d[f.first]});
}
}
}
return d[2 + n] != INF;
}
void solve()
{
int m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
dist[i][j] = INF;
}
dist[i][i] = 0;
}
int ans = 0;
while (m--)
{
int x, y, z;
cin >> x >> y >> z;
mc[x].push_back({y, z});
dist[x][y] = min(dist[x][y], z);
outdeg[x]++;
indeg[y]++;
ans += z;
}
for (int k = 1; k <= n; k++)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
for (int i = 1; i <= n; i++)
{
int dx = outdeg[i] - indeg[i];
if (dx < 0)
{
flowedge[1].push_back({1 + i, 0});
flowedge[1 + i].push_back({1, 0});
cap[1][1 + i] = -dx;
for (int j = 1; j <= n; j++)
{
if (i != j && outdeg[j] - indeg[j] > 0 && dist[i][j] < INF)
{
flowedge[1 + i].push_back({1 + j, dist[i][j]});
flowedge[1 + j].push_back({1 + i, -dist[i][j]});
cap[1 + i][1 + j] = INF;
}
}
}
else
{
flowedge[1 + i].push_back({2 + n, 0});
flowedge[2 + n].push_back({1 + i, 0});
cap[1 + i][2 + n] = dx;
}
}
bf();
while (djk())
{
int nod = 2 + n, mn = INF;
while (nod != 1)
{
mn = min(mn, cap[t[nod]][nod]);
nod = t[nod];
}
ans += mn * pr[2 + n];
nod = 2 + n;
while (nod != 1)
{
cap[t[nod]][nod] -= mn;
cap[nod][t[nod]] += mn;
nod = t[nod];
}
for (int i = 1; i <= 2 + n; i++)
{
aux[i] = d[i];
}
}
cout << ans << "\n";
}
signed main()
{
#ifdef LOCAL
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#else
freopen("traseu.in", "r", stdin);
freopen("traseu.out", "w", stdout);
#endif // LOCAL
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
long long tt;
tt = 1;
while (tt--)
{
solve();
}
return 0;
}