zoukankan      html  css  js  c++  java
  • 【[NOI2006]最大获利】

    题目

    并不知到为什么这道题讲了这么久

    我们发现这道题就是最小割的板子啊,完全可以套上文理分科的板子

    把每个机器和(T)连边,容量为(p_i),这些(p_i)并不计入总贡献

    对于每一个要求我们设置一个新虚点(x)(S)(x)连边,容量为(C_i)(x)分别向(A_i)(B_i)连边容量为(inf)

    一遍最小割就可以了

    发现这个模型还可以推广到最大密度子图里去

    就是让你选择一个一个子图,设

    [d=frac{|E|}{|V|} ]

    使得(d)最大

    看到这个先二分(d)看看能否使得(d)更大一点

    显然需要满足

    [|E|-d|V|>=0 ]

    发现一个边连接两个点这不正好和这道题一样吗

    于是割掉一个点的代价是(d),一条边的收益是(1)就没了

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define re register
    #define maxn 550005
    #define LL long long
    #define inf 999999999
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    struct E{int v,nxt,w,f;}e[maxn<<2];
    int head[maxn],cur[maxn],d[maxn];
    int n,m,num=1,S,T,ans;
    int a[5005];
    inline void add(int x,int y,int w) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;e[num].w=w;}
    inline void C(int x,int y,int w) {add(x,y,w),add(y,x,0); }
    inline int BFS()
    {
    	std::queue<int> q;
    	for(re int i=S;i<=T;i++) cur[i]=head[i],d[i]=0;
    	d[S]=1,q.push(S);
    	while(!q.empty())
    	{
    		int k=q.front();q.pop();
    		for(re int i=head[k];i;i=e[i].nxt)
    		if(!d[e[i].v]&&e[i].w>e[i].f) d[e[i].v]=d[k]+1,q.push(e[i].v);
    	}
    	return d[T];
    }
    int dfs(int x,int now)
    {
    	if(x==T||!now) return now;
    	int flow=0,ff;
    	for(re int& i=cur[x];i;i=e[i].nxt)
    	if(d[e[i].v]==d[x]+1)
    	{
    		ff=dfs(e[i].v,min(e[i].w-e[i].f,now));
    		if(ff<=0) continue;
    		e[i].f+=ff,e[i^1].f-=ff;
    		now-=ff,flow+=ff;
    		if(!now) break;
    	}
    	return flow;
    }
    int main()
    {
    	n=read(),m=read();
    	for(re int i=1;i<=n;i++) a[i]=read();
    	int x,y,z;
    	T=n;
    	for(re int i=1;i<=m;i++)
    	{
    		x=read(),y=read(),z=read();ans+=z;
    		++T;C(S,T,z),C(T,x,inf),C(T,y,inf);
    	} 
    	++T;
    	for(re int i=1;i<=n;i++) C(i,T,a[i]);
    	while(BFS()) ans-=dfs(S,inf);
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    spring中的bean
    在Eclipse上使用Maven
    类加载机制
    jstack简单使用,定位死循环、线程阻塞、死锁等问题
    “心若冰清,天塌不惊”,道家文化原文欣赏,你值得收藏研读!
    【干货分享】可能是东半球最全的.NET Core跨平台微服务学习资源
    Oracle 查询两个时间段内的所有日期列表
    SQL Server中获取指定时间段内的所有月份
    天气预报接口
    pixel和nexus设备安卓9.0/8.1/7.1.x/6.x WiFi和信号图标出现叉x号或者感叹号的消除办 法
  • 原文地址:https://www.cnblogs.com/asuldb/p/10331073.html
Copyright © 2011-2022 走看看