POJ - 3155 Hard Life
Posted mingsd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ - 3155 Hard Life相关的知识,希望对你有一定的参考价值。
一道裸的最大密度子图的题目。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 6 #define LL long long 7 #define ULL unsigned LL 8 #define fi first 9 #define se second 10 #define pb push_back 11 #define lson l,m,rt<<1 12 #define rson m+1,r,rt<<1|1 13 #define max3(a,b,c) max(a,max(b,c)) 14 #define min3(a,b,c) min(a,min(b,c)) 15 typedef pair<int,int> pll; 16 const LL INF = 0x3f3f3f3f3f3f3f3f; 17 const int inf = 0x3f3f3f3f; 18 const LL mod = (int)1e9+7; 19 const int N = 120; 20 const int M = 10000; 21 double eps = 1e-6; 22 int head[N], deep[N], cur[N]; 23 int u[M], v[M]; 24 int vis[N], d[N]; 25 double w[M]; int to[M], nx[M]; 26 int n, m, tot; 27 void add(int u, int v,double val){ 28 w[tot] = val; to[tot] = v; 29 nx[tot] = head[u]; head[u] = tot++; 30 w[tot] = 0; to[tot] = u; 31 nx[tot] = head[v]; head[v] = tot++; 32 } 33 int bfs(int s, int t){ 34 queue<int> q; 35 memset(deep, 0, sizeof(int)*(n+3)); 36 q.push(s); 37 deep[s] = 1; 38 while(!q.empty()){ 39 int u = q.front(); 40 q.pop(); 41 for(int i = head[u]; ~i; i = nx[i]){ 42 if(w[i] > 0 && deep[to[i]] == 0){ 43 deep[to[i]] = deep[u] + 1; 44 q.push(to[i]); 45 } 46 } 47 } 48 if(deep[t] > 0) return 1; 49 return 0; 50 } 51 double Dfs(int u, int t, double flow){ 52 if(u == t) return flow; 53 for(int &i = cur[u]; ~i; i = nx[i]){ 54 if(deep[u] + 1 == deep[to[i]] && w[i] > 0){ 55 double di = Dfs(to[i], t, min(w[i], flow)); 56 if(di > 0){ 57 w[i] -= di, w[i^1] += di; 58 return di; 59 } 60 } 61 } 62 return 0; 63 } 64 65 int Dinic(int s, int t){ 66 double ans = 0, tmp; 67 while(bfs(s, t)){ 68 for(int i = 0; i <= n+1; i++) cur[i] = head[i]; 69 while(tmp = Dfs(s, t, INF)) ans += tmp; 70 } 71 return ans; 72 } 73 74 bool check(double x){ 75 memset(head, -1, sizeof(int) * (n+2)); 76 tot = 0; 77 int s = 0, t = n + 1; 78 for(int i = 1; i <= m; i++){ 79 add(u[i], v[i], 1); 80 add(v[i], u[i], 1); 81 } 82 for(int i = 1; i <= n; i++){ 83 add(s, i, m); 84 add(i, t, m+2*x-d[i]); 85 } 86 return (m*n-Dinic(s,t))/2.0 >= 1e-6; 87 } 88 89 void Find(int x){ 90 vis[x] = 1; 91 for(int i = head[x]; ~i; i = nx[i]) 92 if(w[i] > 0 && !vis[to[i]]) 93 Find(to[i]); 94 } 95 96 int main(){ 97 while(~scanf("%d%d", &n, &m)){ 98 if(m == 0){ 99 printf("1 1 "); 100 continue; 101 } 102 memset(d, 0, sizeof(int)*(n+1)); 103 for(int i = 1; i <= m; i++){ 104 scanf("%d%d", &u[i], &v[i]); 105 d[u[i]]++; d[v[i]]++; 106 } 107 double l = 0, r = m, mid; 108 while(r - l >= 1.0/n/n){ 109 mid = (l+r)/2; 110 if(check(mid)) l = mid; 111 else r = mid; 112 } 113 check(l); 114 memset(vis, 0, sizeof(vis)); 115 Find(0); 116 int ans = 0; 117 for(int i = 1; i <= n; i++) ans += vis[i]; 118 printf("%d ", ans); 119 for(int i = 1; i <= n; i++) 120 if(vis[i]) printf("%d ", i); 121 } 122 return 0; 123 }
以上是关于POJ - 3155 Hard Life的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3155 Hard Life(最大密度子图+改进算法)