POJ 3155 Hard Life (maximum density sub-graph + improved algorithm)

Source: Internet
Author: User
Tags acos bitset integer numbers cmath

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, aibi) 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≤ kn)-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, &AMP;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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.