poj3155 最大密度子图

求最大密度子图

记得在最后一次寻找的时候记得将进入的边放大那么一点点,这样有利于当每条边都满流的情况下会选择点

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int maxn=105;
const double eps=0.00000001;
const double INF=10005*10005;
vector<int>ans;
struct Dinic
{
     struct Edge
     {
         int from,to;
         double cap,flow;
         Edge(int cfrom=0,int cto=0,double ccap=0,double cflow=0)
         {
             from=cfrom; to=cto; cap=ccap; flow=cflow;
         }
     };
     int n,m,s,t;
     vector<Edge>edges;
     vector<int>G[maxn];
     bool vis[maxn];
     int d[maxn];
     int cur[maxn];
     void init(int n)
     {
         this->n=n;
         m=0;
         edges.clear();
         for(int i=0; i<=n; i++)G[i].clear();
     }
     void AddEdge(int from,int to,double cap)
     {
           edges.push_back(Edge(from,to,cap,0));
           edges.push_back(Edge(to,from,0,0));
           m+=2;
           G[from].push_back(m-2);
           G[to].push_back(m-1);
     }
     bool BFS()
     {
         memset(vis,false,sizeof(vis));
         queue<int>Q;
         Q.push(s);
         d[s]=0;
         vis[s]=1;
         while(!Q.empty())
         {
             int x=Q.front(); Q.pop();
             for(int i=0; i<G[x].size(); i++)
             {
                 Edge &e =edges[G[x][i]];
                 if(vis[e.to]==false&&e.cap>e.flow)
                 {
                     vis[e.to]=1;
                     d[e.to]=d[x]+1;
                     Q.push(e.to);
                 }
             }
         }
         return vis[t];
     }
     double DFS(int x, double a)
     {
         if(x==t||a==0)return a;
        double flow=0,f;
        for(int &i=cur[x]; i<G[x].size(); i++)
        {
            Edge &e=edges[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
     }
     double Maxflow(int s,int t)
     {
         this->s=s; this->t=t;
         double flow=0;
         while(BFS())
         {
             memset(cur,0,sizeof(cur));
             flow+=DFS(s,INF);
         }
         return flow;
     }
     void finde(int x)
     {
         vis[x]=1;
         ans.push_back(x);
         for(int i=0;i<G[x].size(); i++)
         {
             Edge &e=edges[G[x][i]];
             if(vis[e.to]||e.cap<=e.flow)continue;
             finde(e.to);
         }
     }
     void solve()
     {
         memset(vis,false,sizeof(vis));
         vis[s]=1;
         vis[t]=1;
         for(int i=0; i<G[s].size(); i++)
         {
             Edge &e=edges[G[s][i]];
             if(vis[e.to]||e.cap<=e.flow)continue;
                finde(e.to);
         }
     }
}T;
int d[maxn];
int A[1005],B[1005];
double U;
void build(int n,int m,double g,int op=0)
{
    T.init(n+2);
    for(int i=1; i<=n; i++)
    {
        T.AddEdge(n+1,i,U+op*eps*2);
        T.AddEdge(i,n+2,U+g*2-d[i]);
    }
    for(int i=1; i<=m; i++)
    {
        T.AddEdge(A[i],B[i],1);
        T.AddEdge(B[i],A[i],1);
    }
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)==2)
    {
        if(m==0)
        {
            printf("1\n1\n");continue;
        }
        memset(d,0,sizeof(d));
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&A[i],&B[i]);
            d[A[i]]++;d[B[i]]++;
        }
        U=m;
        double cL=0.0,cR=1.0*m;
        for(int i=0; i<100; i++)
        {
            double mid=(cL+cR)/2;
            build(n,m,mid);
            double ans=T.Maxflow(n+1,n+2);
            ans=(U*n-ans)/2;
            if(ans>0) cL=mid;
            else cR=mid;
        }
        build(n,m,cL,1);
        T.Maxflow(n+1,n+2);
        ans.clear();
        T.solve();
        sort(ans.begin(),ans.end());
        int ge=unique(ans.begin(),ans.end())-ans.begin();
        printf("%d\n",ge);
        for(int i=0; i<ge;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

 

posted @ 2015-10-29 17:53  来自大山深处的菜鸟  阅读(390)  评论(0编辑  收藏  举报