zoukankan      html  css  js  c++  java
  • 【UVA1389】Hard Life(分数规划+网络流)

    点此看题面

    • 给定一张(n)个点(m)条边的无向图,求最大密度子图(即边数除以点数最大的导出子图)。
    • (nle100,mle1000)

    分数规划

    这种问题一看就是分数规划。

    我们直接二分答案(x),则(frac EPge x)就可以写成(E-x imes Pge 0)

    即选择每条边的价值是(1),每个点的价值是(-x)

    最大权闭合子图

    考虑只有选了两个端点,才能选择这条边,是一个经典的最大权闭合子图模型。

    注意有可能不选任何点会取得最优价值,因此我们最大流之后需要加上判断选择的点数不为(0)

    至于如何判断一个点是否被选择,根据最大权闭合子图模型的建图方式,断开与超级汇相连的边表示选择,那么此时就与超级源连通。即从超级源出发存在一条到该点的增广路径,也就是最后一次(BFS)时的(dep ot=-1)

    (O(Dinic))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100
    #define M 1000
    #define INF 1e9
    #define DB double
    using namespace std;
    int n,m;struct line {int x,y;}p[M+5];
    namespace Dinic
    {
    	#define PS (N+M+2)
    	#define ES (N+3*M)
    	#define s (n+m+1)
    	#define t (n+m+2)
    	#define E(x) ((((x)-1)^1)+1)
    	#define add(x,y,f) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].F=f)
    	int ee,lnk[PS+5],cur[PS+5];struct edge {int to,nxt;DB F;}e[2*ES+5];
    	I void Cl() {ee=0;for(RI i=1;i<=t;++i) lnk[i]=0;}
    	I void Add(CI x,CI y,Con DB& f) {add(x,y,f),add(y,x,0);}
    	int q[PS+5],D[PS+5];I bool BFS()
    	{
    		RI i,k,H=1,T=1;for(i=1;i<=t;++i) D[i]=-1;D[q[1]=s]=0;
    		W(H<=T&&!~D[t]) for(i=lnk[k=q[H++]];i;i=e[i].nxt)
    			e[i].F&&!~D[e[i].to]&&(D[q[++T]=e[i].to]=D[k]+1);return ~D[t];
    	}
    	I DB DFS(CI x=s,DB f=INF)
    	{
    		if(x==t||!f) return f;RI i;DB o,g=0;for(i=cur[x];i;i=e[i].nxt)
    		{
    			if(D[e[i].to]^(D[x]+1)||!(o=DFS(e[i].to,min(f,e[i].F)))) continue;
    			if(g+=o,e[i].F-=o,e[E(i)].F+=o,!(f-=o)) break;
    		}return cur[x]=i,g;
    	}
    	I DB MaxFlow(Con DB& x)//最大权闭合子图模型
    	{
    		RI i;for(Cl(),i=1;i<=n;++i) Add(i,t,x);//点向超级汇
    		for(i=1;i<=m;++i) Add(s,n+i,1),Add(n+i,p[i].x,INF),Add(n+i,p[i].y,INF);//超级源向边,边向点
    		DB f=0;W(BFS()) memcpy(cur,lnk,sizeof(cur)),f+=DFS();return f;//最大流
    	}
    	I bool Check(CI x) {return ~D[x];}//判断是否选择(是否与超级源连通)
    }
    int main()
    {
    	RI i,c;DB l,r,mid,res;W(scanf("%d%d",&n,&m)==2)
    	{
    		for(i=1;i<=m;++i) scanf("%d%d",&p[i].x,&p[i].y);
    		if(!m) {puts("1
    1
    ");continue;}//特判没有边的情况
    		l=0,r=m;W(r-l>1e-6) {res=m-Dinic::MaxFlow(mid=(l+r)/2);//分数规划
    			for(i=1;i<=n;++i) if(Dinic::Check(i)) break;i<=n&&res>0?l=mid:r=mid;}//必须有点被选择
    		for(Dinic::MaxFlow(l),c=0,i=1;i<=n;++i) Dinic::Check(i)&&++c;printf("%d
    ",c);
    		for(i=1;i<=n;++i) Dinic::Check(i)&&printf("%d
    ",i);putchar('
    ');
    	}return 0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    convert image to base64 and post to RESTful wcf
    在android webview实现截屏的手动tounchmove裁剪图片
    How to use jquery ajax and android request security RESTful WCF
    using swfUpload in asp.net mvc
    using HttpClient and sending json data to RESTful server in adroind
    ODP.NET数据访问
    android image watermark
    解决国内不能访问github的问题
    idapro权威指南第二版阅读笔记第九章 交叉引用和绘图功能
    idapro权威指南第二版阅读笔记第二章 逆向和反汇编工具
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/UVA1389.html
Copyright © 2011-2022 走看看