zoukankan      html  css  js  c++  java
  • 网络流(最大密集度子图,分数规划):UvaLive 3709 Hard Life

      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 harderst to manage and make it Scott's team. Please, help him.

    epsfbox{p3709.eps}

      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 $ {frac{{5}}{{4}}}$ . If we add person number 3 to the team then hardness factor decreases to $ {frac{{6}}{{5}}}$ .

    Input

    The input will contain several test cases, each of them as described below. Consecutive test cases are separated by a single blank line.


      The first line of the input contains two integer numbers n and m (1$ le$n$ le$100, 0$ le$m$ le$1000) . Here n is a total number of people in the company (people are numbered from 1 to n ), and m is the number of pairs of people who work poorly in the same team. Next m lines describe those pairs with two integer numbers ai and bi (1$ le$ai, bi$ le$n, ai $ 
eq$ bi) on a line. The order of people in a pair is arbitrary and no pair is listed twice.

    Output

    For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.


      Write to the output an integer number k (1$ le$k$ le$n) -- the number of people in the hardest team, followed by k lines listing people from this team in ascending order. If there are multiple teams with the same hardness factor then write any one.

    Note, that in the last example any team has hardness factor of zero, and any non-empty list of people is a valid answer.

    Sample Input

    5 6 
    1 5 
    5 4 
    4 2 
    2 5 
    1 2 
    3 1 
    
    4 0
    

    Sample Output

    4 
    1 
    2 
    4 
    5 
    
    1 
    1
    

      

      胡博涛论文有提到。

      WA67发,都不敢刷Uva了。

      原因是最后的答案不能用lam获得,因为lam不一定是最优解,而且还会得到错误答案。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <queue>
      5 using namespace std;
      6 const int maxn = 100000;
      7 const int maxm = 1000010;
      8 const double INF = 0x3fffffff;
      9 const double eps = 1e-8;
     10 int n,m;
     11 
     12 struct Max_Flow{
     13     int cnt,fir[maxn],fron[maxn];
     14     int tot,to[maxm],nxt[maxm];
     15     double cap[maxm];queue<int>q;
     16     int dis[maxn],gap[maxn],path[maxn];
     17     void Init(int tot_=0){
     18         memset(fir,0,sizeof(fir));
     19         memset(dis,0,sizeof(dis));
     20         memset(gap,0,sizeof(gap));
     21         cnt=1;tot=tot_;
     22     }
     23     void add(int a,int b,double c){
     24         nxt[++cnt]=fir[a];
     25         fir[a]=cnt;
     26         cap[cnt]=c;
     27         to[cnt]=b;
     28     }
     29     
     30     void addedge(int a,int b,double c){
     31         add(a,b,c);
     32         add(b,a,0);
     33     }
     34     
     35     bool BFS(int s,int t){
     36         dis[t]=1;q.push(t);
     37         while(!q.empty()){
     38             int x=q.front();q.pop();
     39             for(int i=fir[x];i;i=nxt[i])
     40                 if(!dis[to[i]]){
     41                     dis[to[i]]=dis[x]+1;
     42                     q.push(to[i]);
     43                 }
     44         }
     45         return dis[s];
     46     }
     47 
     48     double Aug(int s,int t){
     49         int p=t;double f=INF;
     50         while(p!=s){
     51             f=min(f,cap[path[p]]);
     52             p=to[path[p]^1];
     53         }
     54         p=t;
     55         while(p!=s) {
     56             cap[path[p]]-=f;
     57             cap[path[p]^1]+=f;
     58             p=to[path[p]^1];
     59         }
     60         return f;
     61     }
     62     
     63     double ISAP(int s,int t){
     64         if(!BFS(s,t));
     65         for(int i=s;i<=t;i++)gap[dis[i]]+=1;
     66         for(int i=s;i<=t;i++)fron[i]=fir[i];
     67         int p=s;double ret=0;
     68         while(dis[s]<=tot){
     69             if(p==t){
     70                 ret+=Aug(s,t);
     71                 p=s;
     72             }
     73             int &ii=fron[p];
     74             for(;ii;ii=nxt[ii])if(cap[ii])
     75                 if(dis[p]==dis[to[ii]]+1)
     76                     break;
     77             if(ii)
     78                 path[p=to[ii]]=ii;
     79             else{
     80                 if(--gap[dis[p]]==0)break;
     81                 int minn=tot+1;
     82                 for(int i=fir[p];i;i=nxt[i])
     83                     if(cap[i]>eps)minn=min(minn,dis[to[i]]);
     84                 gap[dis[p]=minn+1]+=1;fron[p]=fir[p];
     85                 if(p!=s)p=to[path[p]^1];    
     86             }            
     87         }
     88         return ret;
     89     }
     90 }isap;
     91 
     92 int vis[maxn],ans;
     93 void DFS(int x){
     94     vis[x]=true;
     95     if(x>=1&&x<=n)ans+=1;
     96     for(int i=isap.fir[x];i;i=isap.nxt[i])
     97         if(!vis[isap.to[i]]&&isap.cap[i]>eps)
     98             DFS(isap.to[i]);
     99 }
    100 
    101 int x1[maxm],y1[maxm];
    102 void Build(double lam){
    103     isap.Init(n+m+2);
    104     for(int i=1;i<=m;i++){
    105         int u=x1[i],v=y1[i];
    106         isap.addedge(0,n+i,1.0);
    107         isap.addedge(n+i,u,INF);
    108         isap.addedge(n+i,v,INF);
    109     }
    110     for(int i=1;i<=n;i++)
    111         isap.addedge(i,n+m+1,lam);
    112 }
    113 
    114 void Solve(){
    115     
    116     int s=0,t=n+m+1;
    117     double l=0,r=m,lam;
    118     while (r-l>=1.0/n/n){
    119         lam=(l+r)/2;Build(lam);
    120         double ret=isap.ISAP(s,t);
    121         if(1.0*m-ret<eps)r=lam;
    122         else l=lam;
    123     }
    124     Build(l);isap.ISAP(s,t);
    125     memset(vis,0,sizeof(vis));
    126     ans=0;DFS(s);printf("%d
    ",ans);
    127     for (int i=1;i<=n;i++)
    128         if(vis[i])printf("%d
    ", i);
    129 }
    130 
    131 int main(){
    132     while(scanf("%d%d",&n,&m)!=EOF){
    133         for(int i=1;i<=m;i++)
    134             scanf("%d%d",&x1[i],&y1[i]);
    135         if(!m){
    136             printf("1
    1
    ");
    137             continue;
    138         }
    139         Solve();
    140     }
    141     return 0;    
    142 }
  • 相关阅读:
    分享我的2014年3月unity3d面试题与参考答案(转)
    Unity3D 面试ABC
    MiniJson解释Json字符串
    Unity3D研究之支持中文与本地文件的读取写入(转)
    unity3d--NGUI制作中文字体
    吊炸天之十步完全理解SQL
    mysql主从同步碰到的问题
    Redis 安装碰到问题
    在Centos系统下使用命令安装gnome图形界面程序
    centos7 网络问题
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5651375.html
Copyright © 2011-2022 走看看