Minimum weight ring coverage problem: the sum of the weights of the selected edges is obtained by covering all points with several rings.
Splitting idea + finding the maximum +km algorithm for minimum turn
#include <cstdlib> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm > #include <fstream> #include <iostream> #define REP (i, L, R) for (int i=l; i<=r; i++) #define CLR (x, C) MEMS ET (x, C, sizeof (x)) #define N 123#define MAX 1<<30#define ll long longusing namespace Std;int read () {int x=0, f=1; ch Ar Ch=getchar (); while (ch< ' 0 ' | | ch> ' 9 ') {if (ch== '-') f=-1; Ch=getchar ();} while (ch>= ' 0 ' && ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} int n, M, L[n], st[n], lx[n], ly[n], V[n][n];bool vx[n], vy[n];bool Find (int x) {vx[x]=1;rep (y, 1, N) if (!vy[y]) {int a=lx[ X]+ly[y]-v[x][y];if (!a) {vy[y]=1; if (!l[y] | | Find (L[y])) {l[y]=x; return true;}} else St[y]=min (St[y], a);} return false;} int km () {Rep (i, 1, N) lx[i]=-max; CLR (ly, 0), CLR (l, 0); Rep (i, 1, N) Rep (j, 1, N) if (Lx[i]<v[i][j]) Lx[i]=v[i][j];rep ( I, 1, N) {rep (j, 1, N) St[j]=max, while (1) {CLR (VX, 0), CLR (vy, 0), if (Find (i)) break, int A=max;rep (j, 1, N) if (!vy[j] && st[j]<a) A=st[j];rep (j, 1, N) if (Vx[j]) Lx[j]-=a;rep (j, 1, N) if (vy[j]) ly[j]+=a; else St[j]-=a;}} int Ans=0;rep (i, 1, N) if (!l[i] | | v[l[i]][i]==-max) return-1; else Ans+=v[l[i]][i];return-ans;} int main () {while (~scanf ("%d%d", &n, &m)) {Rep (i, 1, N) Rep (j, 1, N) v[i][j]=max;rep (i, 1, m) {int x=read (), Y=rea D (), Z=read (); if (v[x][y]>z) v[x][y]=z; }rep (i, 1, N) Rep (j, 1, N) v[i][j]*=-1;printf ("%d\n", km ());} return 0;}
HDU-1853 Cyclic Tour