zoukankan      html  css  js  c++  java
  • [POJ 3155]Hard Life(最大密度子图)

    Description

    John is a Chief Executive Officer at a privately owned medium size company. The owner of the company has decided to make his son Scott a manager in the company. John fears that the owner will ultimately give CEO position to Scott if he does well on his new manager position, so he decided to make Scott’s life as hard as possible by carefully selecting the team he is 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, the harder is this team to manage. John wants to find a group of people in the company that are hardest to manage and make it Scott’s team. Please, help him.

    In 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 is equal to 54. If we add person number 3 to the team then hardness factor decreases to 65.

    Solution

    题面丧病…公司的大股东要把自己的儿子放进公司,很可能会取代你的位置,公司里的人与人间有若干条不和的关系,你希望给他分配一个不和关系组数/人数的值最大的垃圾小组

    最大密度子图·裸

    我用的是naive方法…并没有学论文里的Improved Algorithm

    注意最好二分之后check一遍l,用mid很容易出现最后图里一个点也没有的情况

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    #define INF 1e20
    #define eps 1e-6
    using namespace std;
    int s,t,n,m,head[2005],level[2005],u[1005],v[1005],cnt,ans;
    bool vis[1005];
    struct Node
    {
        int next,to;
        double cap;
    }Edges[10005];
    void addedge(int u,int v,double c)
    {
        Edges[cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].to=v;
        Edges[cnt++].cap=c;
    }
    void insert(int u,int v,double c)
    {
        addedge(u,v,c);
        addedge(v,u,0);
    }
    queue<int>q;
    bool bfs()
    {
        memset(level,-1,sizeof(level));
        q.push(s),level[s]=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];~i;i=Edges[i].next)
            {
                int v=Edges[i].to;
                if(level[v]==-1&&Edges[i].cap>eps)
                level[v]=level[u]+1,q.push(v);
            }
        }
        if(level[t]==-1)return false;
        return true;
    }
    double dfs(int u,double f)
    {
        if(u==t||fabs(f)<eps)return f;
        double flow=0,d;
        for(int i=head[u];~i&&flow<f;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(level[v]==level[u]+1&&Edges[i].cap>eps)
            {    
                d=dfs(v,min(Edges[i].cap,f-flow));
                flow+=d;
                Edges[i].cap-=d;
                Edges[i^1].cap+=d;
            }
        }
        if(flow<eps)level[u]=-1;
        return flow;
    }
    double dinic()
    {
        double res=0,d;
        while(bfs())
        {
            while((d=dfs(s,INF))>eps)res+=d;
        }
        return res;
    }
    void find()
    {
        memset(vis,0,sizeof(vis));
        vis[s]=1,q.push(s);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            if(u>0&&u<=n)++ans;
            for(int i=head[u];~i;i=Edges[i].next)
            {
                int v=Edges[i].to;
                if(!vis[v]&&Edges[i].cap>eps)vis[v]=1,q.push(v);
            }
        }
    }
    bool check(double mid)
    {
        double res;
        memset(head,-1,sizeof(head));
        s=0,t=n+m+1,res=m,cnt=0;
        for(int i=1;i<=n;i++)insert(i,t,mid);
        for(int i=1;i<=m;i++)
        {
            insert(s,i+n,1);
            insert(i+n,u[i],INF),insert(i+n,v[i],INF);
        }
        res-=dinic();
        return res<eps;
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            if(!m){printf("1
    1
    ");return 0;}
            for(int i=1;i<=m;i++)scanf("%d%d",&u[i],&v[i]);
            double l=0,r=m,mid;
            while(r-l>1.0/n/n)
            {
                mid=(l+r)/2;
                if(check(mid))r=mid;else l=mid;
            }
            check(l);
            ans=0,find();
            printf("%d
    ",ans);
            for(int i=1;i<=n;i++)if(vis[i])printf("%d
    ",i);
        }
        return 0;
    }
  • 相关阅读:
    算法学习笔记: 珂朵莉树
    算法学习笔记:2SAT
    0x62 图论最小生成树
    Codeforces Round #632 (Div. 2) C. Eugene and an array(尺取法/前缀和)
    BZOJ1912 异象石(LCA/DFS序/set)
    (六1)Firefox插件安装
    (六2)八种定位方式为了查找元素
    (六3)从查找元素到操作元素
    【OSI】网络协议模型
    读《Wireshark网络分析就这么简单》读书笔记
  • 原文地址:https://www.cnblogs.com/Zars19/p/6953006.html
Copyright © 2011-2022 走看看