您的位置:首页 > 其它

最大密度子图poj3155

2017-01-24 22:20 218 查看
 

 

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int N=3105;
const int inf=0x3f3f3f3f;
const double eps=1e-8;

int n,m,S,T;
int x
,y
;

int head
,tot;
struct aa
{
int to,pre;
double flow,cap;
}edge[N*80];
void addedge(int u,int v,double c)
{
edge[++tot].to=v;edge[tot].pre=head[u];edge[tot].cap=c;edge[tot].flow=0;head[u]=tot;
edge[++tot].to=u;edge[tot].pre=head[v];edge[tot].cap=0;edge[tot].flow=0;head[v]=tot;
}

int lev
;
bool bfs()
{
memset(lev,0,sizeof(lev));
lev[S]=1;
queue<int> q;q.push(S);
while (!q.empty())
{
int u=q.front();q.pop();
for (int i=head[u];i;i=edge[i].pre)
if (lev[edge[i].to]==0&&edge[i].cap-edge[i].flow>eps)
{
lev[edge[i].to]=lev[u]+1;
if (edge[i].to==T) return true;
q.push(edge[i].to);
}
}
return false;
}
int cur
;
double dfs(int u,double maxflow)
{
if (maxflow<eps||u==T) return maxflow;
double ans=0;
for (int &i=cur[u];i;i=edge[i].pre)
if (lev[edge[i].to]==lev[u]+1)
{
double flow=dfs(edge[i].to,min(maxflow,edge[i].cap-edge[i].flow));
maxflow-=flow;
ans+=flow;
edge[i].flow+=flow;
edge[((i-1)^1)+1].flow-=flow;
if (maxflow<eps) return ans;
}
return ans;
}

double work()
{
double ans=0;
while (bfs())
{
for (int i=0;i<=T;i++) cur[i]=head[i];
ans+=dfs(S,1e9);
}
return ans;
}

double pan(double ans)
{
memset(head,0,sizeof(head));tot=0;
S=0,T=n+m+1;
for (int i=1;i<=n;i++) addedge(i,T,ans);
for (int i=1;i<=m;i++)
{
addedge(S,i+n,1.0);
addedge(i+n,x[i],1e9);
addedge(i+n,y[i],1e9);
}
return 1.0*m-work();
}
int tmp
,ans;

void dfs(int u)
{
lev[u]=1;
if (u>=1&&u<=n) ans++;
for (int i=head[u];i;i=edge[i].pre)
if (edge[i].cap-edge[i].flow>0&&lev[edge[i].to]==0) dfs(edge[i].to);
}
int main()
{
scanf("%d%d",&n,&m);
if (m==0) {
printf("1\n1");
return 0;
}
for (int i=1;i<=m;i++) scanf("%d%d",&x[i],&y[i]);
double l=0,r=1e7,mid;
while (l+eps<r)
{
mid=(l+r)/2;
if (pan(mid)<eps) r=mid;else l=mid;
}
pan(l);
memset(lev,0,sizeof(lev));
dfs(S);
printf("%d\n",ans);
for (int i=1;i<=n;i++) if (lev[i]>0) printf("%d\n",i);
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: