POJ PKU 3155 最大密度子图
(2010-10-08 10:35:44)
标签:
pojpku3155最大密度子图it |
分类: 网络流 |
题目描述:
给你一个无向图,让你选一个子图,使这个子图的密度(边数/点数)最大。
输出这个子图的每个点,SPJ,如果多个最大密度,输出任意一个子图就好了。
解题报告:
胡伯涛《最小割模型在信息学竞赛中的应用》有详细的证明与解释,不在这里赘述。只写做法:
统计出每个点的度d[i],点的下标1到n
原点s,汇点t。设边数有m。
原点s和1~n点连接,容量为m。
对于原图中的无向边a,b,连接a->b,容量1,连接b->a,容量1。
二分枚举一个double数字,左边界L = 0,右边界R = m。
跳出条件是while(R – L >= (1 / n / n))
对于每一个mid = (L + R) * 0.5。
1~n每个点和t连接,容量为m + 2 * mid – d[i]。
求最大流得到一个double数字ans。
如果 (m * n – ans) * 0.5大于0, L = mid
否则R = mid。
最后跳出的L就是最大密度。
拿这个L再重新建图,求最大流。
然后从s出发bfs或者dfs,走残留容量大于0的边,所有能到达的点就是答案。
关键部分:
double l = 0, r = m, mmin = 1.0 / n / n;
while(r - l >= mmin)
{
}
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define size 2000
#define eps 1e-7
struct edge{int from, to, next;double val;}e[140000];
int v[size], que[size], dis[size], cnt, cur[size];
void insert(int from, int to, double va)
{
}
bool bfs(int n, int s, int t)
{
}
double Dinic(int n, int s, int t)
{