Hard Life
Time Limit: 8000MS |
|
Memory Limit: 65536K |
Total Submissions: 9012 |
|
Accepted: 2614 |
Case Time Limit: 2000MS |
|
Special Judge |
Description
John is a chief Executive Officer @ a privately owned medium size company. The owner of the company had decided to make he son Scott a manager in the company. John fears that the owner would ultimately give CEO position to Scott if he does well on his new manager position, so he de Cided to make Scott's life as hard as possible by carefully selecting the team he's going to manage in the company.
John knows which pairs of his people work poorly in the same team. John introduced a hardness factor of a team-it is a number of pairs of people from this team who work poorly in The same team divided by the total number of people in the team. The larger is the hardness factor, and the harder is this team to manage. John wants to find a group of people in the company that is hardest to manage and make it Scott's team. Please, help him.
The example on the picture the hardest team consists of people 1, 2, 4, and 5. Among 4 of them 5 pairs work poorly in the same team, thus hardness factor are equal to 5⁄4. If we add person number 3 to the team then hardness factor decreases to 6⁄5.
Input
The first line of the input file contains the numbers n and m (1≤ n ≤ 100, 0≤ m ≤1000). Here N -A total number of people in the company (people was numbered from 1 to n), and M is the number of pairs of people who work poorly in the same team. Next m lines describe those pairs with both integer numbers ai and bi (1≤ ai, bi< /c10>≤ n, ai ≠ bi) on a line. The order of people in a pair are arbitrary and no pair is listed twice.
Output
Write to the output file a integer number k (1≤ k ≤ n)-the number of people in the hardest Team, followed by K Lines listing people from the this team in ascending order. If There is multiple teams with the same hardness factor then write any one.
Sample Input
Sample Input #15 1Sample input #24 0
Sample Output
Sample Output #141245Sample output #211
Hint
Note, the last example any team have hardness factor of zero, and any non-empty list of people are a valid answer.
Title Link: POJ 3155
official commentary on the application of minimum cut model of Hubertau Amber in the contest of informatics What does the maximum density sub-graph mean in this paper? is to select a sub-graph, so that its sub-graph ${Edge number \over vertex number}$ maximum, that is ${| E ' | \over | V ' |} $ Max, the latter is not very familiar with the 01 plan very much like, is to make the ratio the largest, then according to 01 planning ideas, set this ratio for $g$, then two separate a $g$ maximum value makes $| E ' |-g*| V ' |>0$, but how do I know $e ' $ and $v ' $ How to fetch AH? look at the inside of the $e ' $ and $v ' $, you can find that if an edge $e_i$ in the edge set $e ' $, then $e_i$ two endpoints $u_i$ and $v_i$ must be in the vertex set $v ' $, that is $e_i$ existence of the necessary condition is $u_i$, $v _i $ two point of existence, and then observe this formula again, you can see the edge as a new virtual point, point or the original point, the point of the virtual point is a positive 1, the point of the original point is negative-G, then as long as in this new figure to find the maximum weight of a closed graph of the maximum weight is this $| E ' |-g*| The maximum value of the V ' |$ is the optimal condition of this equation, and then according to its 0 (or EPS ... ) The relationship between the two points can be, the code nong problem ...
Code:
#include <stdio.h> #include <iostream> #include <algorithm> #include <cstdlib> #include < sstream> #include <numeric> #include <cstring> #include <bitset> #include <string> #include <deque> #include <stack> #include <cmath> #include <queue> #include <set> #include <map >using namespace std, #define INF 0x3f3f3f3f#define LC (x) (x<<1) #define RC (x) ((x<<1) +1) #define MID (x, y) ( (x+y) >>1) #define CLR (Arr,val) memset (arr,val,sizeof (arr)) #define FAST_IO Ios::sync_with_stdio (false); Cin.tie (0); typedef pair<int, int> pii;typedef long long ll;const double PI = ACOs ( -1.0); const int N = 110;const int M = 101 0;const double EPS = 1e-8;struct edge{int to, NXT; Double cap; Edge () {} edge (int _to, int _nxt, double _cap): to (_to), NXT (_NXT), Cap (_cap) {}};struct info{int u, v;}; Info E[m];edge e[(N + 3 * m) << 1];int Head[n + m], Tot;int d[n + m];void init () {CLR (head,-1); tot = 0;}inline void Add (int s, int t, double cap) {E[tot] = Edge (t, Head[s], cap); Head[s] = tot++; E[tot] = Edge (S, Head[t], 0); Head[t] = tot++;} int BFS (int s, int t) {queue<int>q; CLR (d,-1); D[s] = 0; Q.push (s); while (! Q.empty ()) {int u = q.front (); Q.pop (); for (int i = head[u]; ~i; i = e[i].nxt) {int v = e[i].to; if (d[v] = =-1 && e[i].cap > 0) {d[v] = D[u] + 1; if (v = = t) return 1; Q.push (v); }}} return ~d[t];} Double dfs (int s, int t, double f) {if (s = = T | | f = = 0) return f; DOUBLE ret = 0; for (int i = head[s]; ~i; i = e[i].nxt) {int v = e[i].to; if (d[v] = = D[s] + 1 && e[i].cap > 0) {Double df = dfs (V, t, Min (f, e[i].cap)); if (df > 0) {e[i].cap-= DF; e[i ^ 1].cap+ = DF; RET + = DF; F-= DF; if (f = = 0) break; }}} if (ret = = 0) D[s] =-1; return ret;} Double dinic (int s, int t) {double ret = 0; while (BFS (s, t)) ret + = DFS (s, T, 1e9); return ret;} Double Maxweight (int n, int m, double g) {init (); int S = 0, T = n + M + 1; int i; for (i = 1; I <= n; ++i)//negative weight points to the meeting point T Add (I, t, G); for (i = 1; I <= m; ++i)//m A positive point is connected from S {Add (S, n + I, 1.0); Add (n + i, e[i].u, 1e9); Original side reserved Add (n + i, E[I].V, 1e9); } return M * 1.0-dinic (S, T); Positive weighted point-maximum flow gets the maximum weight}int main (void) {int n, m, I; while (~SCANF ("%d%d", &n, &m)) {for (i = 1; I <= m; ++i) scanf ("%d%d", &e[i].u, & E[I].V); if (!m) {puts ("1"); Puts ("1"); } else {Double L = 1.0/n, R = m; Double ans = 1; DoublE dx = 1.0/n/n; while (Fabs (r-l) >= dx) {Double mid = (L + R)/2.0; if (Fabs (Maxweight (N, M, mid)) >= eps) {L = mid; Ans = mid; } else R = mid; } maxweight (n, m, ans); vector<int>pos; for (i = 1; I <= n; ++i) if (~d[i]) pos.push_back (i); int sz = Pos.size (); Sort (Pos.begin (), Pos.end ()); printf ("%d\n", SZ); for (i = 0; i < sz; ++i) printf ("%d\n", Pos[i]); }} return 0;}
Improved algorithm: The paper can be $h (g) ={u*n-c[s, T]} \over 2$, which can make $u=m$, and then the new way to build
After the improvement from 600ms to 200ms, the effect is still good
Code:
#include <stdio.h> #include <iostream> #include <algorithm> #include <cstdlib> #include < sstream> #include <numeric> #include <cstring> #include <bitset> #include <string> #include <deque> #include <stack> #include <cmath> #include <queue> #include <set> #include <map >using namespace std, #define INF 0x3f3f3f3f#define LC (x) (x<<1) #define RC (x) ((x<<1) +1) #define MID (x, y) ( (x+y) >>1) #define CLR (Arr,val) memset (arr,val,sizeof (arr)) #define FAST_IO Ios::sync_with_stdio (false); Cin.tie (0); typedef pair<int, int> pii;typedef long long ll;const double PI = ACOs ( -1.0); const int N = 110;const int M = 101 0;const double EPS = 1e-8;struct edge{int to, NXT; Double cap; Edge () {} edge (int _to, int _nxt, double _cap): to (_to), NXT (_NXT), Cap (_cap) {}};struct info{int u, v;}; Info E[m];edge e[(N + M) << 2];int head[n], Tot;int d[n], deg[n];void init () {CLR (head,-1); tot = 0;} InliNE void Add (int s, int t, double cap) {E[tot] = Edge (t, Head[s], cap); Head[s] = tot++; E[tot] = Edge (S, Head[t], 0); Head[t] = tot++;} int BFS (int s, int t) {queue<int>q; CLR (d,-1); D[s] = 0; Q.push (s); while (! Q.empty ()) {int u = q.front (); Q.pop (); for (int i = head[u]; ~i; i = e[i].nxt) {int v = e[i].to; if (d[v] = =-1 && e[i].cap > 0) {d[v] = D[u] + 1; if (v = = t) return 1; Q.push (v); }}} return ~d[t];} Double dfs (int s, int t, double f) {if (s = = T | | f = = 0) return f; DOUBLE ret = 0; for (int i = head[s]; ~i; i = e[i].nxt) {int v = e[i].to; if (d[v] = = D[s] + 1 && e[i].cap > 0) {Double df = dfs (V, t, Min (f, e[i].cap)); if (df > 0) {e[i].cap-= DF; e[i ^ 1].cap + = dF RET + = DF; F-= DF; if (f = = 0) break; }}} if (ret = = 0) D[s] =-1; return ret;} Double dinic (int s, int t) {double ret = 0; while (BFS (s, t)) ret + = DFS (s, T, 1e9); return ret;} Double CST (int n, int m, double g) {init (); Double U = m; int S = 0, T = n + 1; int i; for (i = 1; I <= n; ++i)//<s,v,u> with <v,T,U+2g-dv> {Add (S, I, U); Add (i, T, U + 2 * g-1.0 * deg[i]); } for (i = 1; I <= m; ++i)//(u,v,1) {Add (e[i].u, E[I].V, 1.0); Add (E[I].V, e[i].u, 1.0); } return Dinic (S, T); Direct calculation of the minimum cut value (maximum flow value)}int main (void) {int n, m, I; while (~SCANF ("%d%d", &n, &m)) {CLR (deg, 0); for (i = 1; I <= m; ++i) {scanf ("%d%d", &e[i].u, &E[I].V); ++DEG[E[I].U]; ++DEG[E[I].V]; } if (!m) {puts ("1"); Puts ("1"); } else {Double L = 1.0/n, R = m; Double ans = 1; Double dx = 1.0/n/n; while (Fabs (r-l) >= dx) {Double mid = (L + R)/2.0; Double HG = (M * n * 1.0-CST (n, M, mid))/2; if (Hg >= eps) {L = mid; Ans = mid; } else R = mid; } CST (n, m, ans); vector<int>pos; for (i = 1; I <= n; ++i) if (~d[i]) pos.push_back (i); int sz = Pos.size (); Sort (Pos.begin (), Pos.end ()); printf ("%d\n", SZ); for (i = 0; i < sz; ++i) printf ("%d\n", Pos[i]); }} return 0;}
POJ 3155 Hard life (maximum density sub-graph + improved algorithm)