The K-leleague
Question:
Give n to each other and start the competition. Now I have determined whether it is possible for a person to win the game and lose the game through his/her match with the N-1.
Algorithm:
We can know that I will win the championship, and he will win all the matches against n-1 people. The maximum number of wins is win [I] + A [I] [J]. if the total number of games is big, and others are sure to win the number, then they will not be able to win the championship, right ?. However, there are only two results for a game: I or J. At this time, we can think of how to create a chart, that is, the two people in a game respectively as a node. There is a clear correspondence relationship here, that is, the competition corresponds to two people.
Graph creation:
So now we can think of connecting the starting point to the competition. The capacity is the number of times of the competition, right ?.
Then, we will connect the game to the two players in the game, because this game is only related to the two players, right ?.
Finally, what is the capacity of connecting everyone to the sink? Here, we assume that the X-th individual will win the championship. Therefore, we need to figure out the best result of his victory. Therefore, he must win as much as possible. Therefore, the biggest win for everyone is tot [x]-win [now]. Right ?. That is, the number of wins in the current game cannot exceed tot [x]-win [now]. Because he has exceeded the number, it indicates that X is not the champion. The figure is created. Do you understand ?!
# Include <iostream> # include <algorithm> # include <vector> # include <queue> # include <cstdio> # include <cstring> using namespace STD; const int INF = 1 <20; const int maxn = 1000; /// // struct edge {int from, to, Cap, flow; edge () {}; edge (INT _ from, int _ to, int _ cap, int _ flow): From (_ from ), to (_ to), Cap (_ cap), flow (_ flow) {};}; vector <edge> edges; vector <int> G [maxn]; int d [maxn], cur [maxn ]; Int n, m, SRC, sink; //////////////////////////////////////// /// int A [maxn] [maxn], W [maxn]; int tot [maxn]; void Init () {src = N * n + 2; sink = SRC + 1; for (INT I = 0; I <sink + 2; ++ I) g [I]. clear (); edges. clear ();} void addedge (int from, int to, int cap) {edges. push_back (edge (from, to, Cap, 0); edges. push_back (edge (to, from, 0, 0); int SZ = edges. size (); G [from]. push_back (SZ-2); G [to]. push_back (SZ-1 );} Bool build (int x) {for (INT I = 0; I <n ;++ I) {for (Int J = I + 1; j <N; ++ J) {addedge (SRC, I * n + J, a [I] [J]); // Number of addedge (I * n + J, I + N * n, INF); // which two are playing addedge (I * n + J, J + N * n, INF);} int sum = 0; for (INT I = 0; I <n; ++ I) {If (TOT [x] <W [I]) {// the current number of wins for this individual cannot be the same as that determined by others. Return false;} sum + = tot [x]-W [I]; addedge (I + N * n, sink, TOT [x]-W [I]); // The maximum number of wins} return true;} bool check () {( Int I = 0; I <(INT) g [SRC]. size (); ++ I) {If (G [SRC] [I] & 1) continue; edge & E = edges [G [SRC] [I]; if (E. cap! = E. flow) return false;} return true ;} //////////////////////////////////////// /// bool BFS () {fill (D, D + sink + 2,-1); queue <int> q; d [SRC] = 0; q. push (SRC); While (! Q. empty () {int x = Q. front (); q. pop (); For (INT I = 0; I <(INT) g [X]. size (); ++ I) {edge & E = edges [G [x] [I]; If (d [E. to] =-1 & E. cap> E. flow) {d [E. to] = d [x] + 1; q. push (E. to) ;}} return d [sink]> 0;} int DFS (int x, int A) {If (x = sink | A = 0) return A; int flow = 0, F; For (Int & I = cur [X]; I <(INT) g [X]. size (); ++ I) {edge & E = edges [G [x] [I]; If (d [E. to] = d [x] + 1 & (F = DFS (E. to, min (A, E. cap -E. flow)> 0) {e. flow + = f; edges [G [x] [I] ^ 1]. flow-= f; flow + = f; A-= f; if (a = 0) break;} return flow;} int maxflow () {int flow = 0; while (BFS () {memset (cur, 0, sizeof (cur); flow + = DFS (SRC, INF);} return flow ;} //////////////////////////////////////// // int main () {// freopen ("input.txt", "r", stdin); int t; scanf ("% d", & T); While (t --) {int X; scanf ("% d", & N); For (INT I = 0; I <n; ++ I) scanf ("% d % D ", & W [I], & X); For (INT I = 0; I <n; ++ I) {tot [I] = W [I]; for (Int J = 0; j <n; ++ J) {scanf ("% d", & A [I] [J]); TOT [I] + = A [I] [J] ;}} bool first = true; For (INT I = 0; I <n; ++ I) {Init (); If (! Build (I) continue; maxflow (); If (check () {If (first) printf ("% d", I + 1 ); else printf ("% d", I + 1); first = false ;}} puts ("") ;}return 0 ;}
The K-leleague (network stream, difficult to create images)