SGU 210 Acdream 1227 Beloved Sons KM, sguacdream
Question link: Click the open link
Question:
Given n people
Point permissions of each person
The n rows below indicate the numbers that individuals can obtain (numbers are from 1 to n and cannot be allocated repeatedly)
If this person gets a number, you can get his/her weight.
You can obtain the maximum value and weight.
Q:
Output the number that each person should obtain. If no number is obtained, 0 is output.
Ideas:
KM: each person connects an edge to each number. edge weight is the weight of this person,
The number that this person cannot obtain is connected to an edge with an edge weight of 0.
# Include <stdio. h> # include <string. h> # define M 410 # define inf 0x3f3f3f int n, nx, ny; int link [M], lx [M], ly [M], slack [M], linkx [M]; // lx, ly is the top mark, nx, ny is the number of y points set in x point set, int visx [M], visy [M], w [M] [M]; int DFS (int x) {visx [x] = 1; for (int y = 1; y <= ny; y ++) {if (visy [y]) continue; int t = lx [x] + ly [y]-w [x] [y]; if (t = 0) // {visy [y] = 1; if (link [y] =-1 | DFS (link [y]) {link [y] = x; linkx [x] = y; return 1 ;}} else if (slack [y]> t) // obtain the smallest slack [y] = t;} return 0;} int KM () for slack not in an equal subgraph () {int I, j; memset (link,-1, sizeof (link); memset (ly, 0, sizeof (ly); for (I = 1; I <= nx; I ++) // lx is initialized to the for (j = 1, lx [I] =-inf; j <= ny; j ++) if (w [I] [j]> lx [I]) lx [I] = w [I] [j]; for (int x = 1; x <= nx; x ++) {for (I = 1; I <= ny; I ++) slack [I] = inf; while (1) {memset (visx, 0, sizeof (visx); memset (visy, 0, Sizeof (visy); if (DFS (x) // if (the augmented orbit is found), The point is extended and enters the augmented break of the next point; // if it fails (the augmented orbit is not found), you need to change the vertex labels to increase the number of feasible edges in the graph. // The method is to subtract a constant d from all the labels of the X vertices in the augmented orbit (that is, traversed during the augmented process, // Add a constant d int d = inf; for (I = 1; I <= ny; I ++) if (! Visy [I] & d> slack [I]) d = slack [I]; for (I = 1; I <= nx; I ++) if (visx [I]) lx [I]-= d; for (I = 1; I <= ny; I ++) // after the top mark is modified, we need to subtract the slack value of all Y vertices not in the staggered tree from d if (visy [I]) ly [I] + = d; else slack [I]-= d ;}} int res = 0; for (I = 1; I <= ny; I ++) if (link [I]>-1) res + = w [link [I] [I]; return res ;} template <class T> inline bool rd (T & ret) {char c; int sgn; if (c = getchar (), c = EOF) return 0; while (c! = '-' & (C <'0' | c> '9') c = getchar (); sgn = (c = '-')? -1:1; ret = (c = '-')? 0 :( c-'0'); while (c = getchar (), c> = '0' & c <= '9 ') ret = ret * 10 + (c-'0'); ret * = sgn; return 1;} template <class T> inline void pt (T x) {if (x <0) {putchar ('-'); x =-x;} if (x> 9) pt (x/10 ); putchar (x % 10 + '0');} using namespace std; int a [401]; void build () {for (int I = 1; I <= n; I ++) rd (a [I]), a [I] = a [I] * a [I]; for (int I = 1, siz, u; I <= n; I ++) {memset (w [I], 0, sizeof w [I]); rd (siz); while (siz --) {rd (u); w [I] [U] = a [I] ;}} nx = ny = n; KM () ;}int main () {while (rd (n) {build (); for (int I = 1; I <= n; I ++) {if (w [I] [linkx [I]) pt (linkx [I]); else putchar ('0'); I = n? Puts (""): putchar ('') ;}} return 0 ;}