bzoj4443: [Scoi2015]小凸玩矩阵

本文介绍了一种利用网络流算法解决矩阵元素选择问题的方法,旨在寻找满足特定条件的矩阵元素组合,通过构造网络流模型并采用二分查找确定最优解。

Description

小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少。

Input

第一行给出三个整数N,M,K
接下来N行,每行M个数字,用来描述这个矩阵

Output

如题 

Sample Input

3 4 2
1 5 6 6
8 3 4 3
6 8 6 3

Sample Output

3

题解:
看了讨论就发现是二分了,二分ans,判断如果小于ans的有n-k+1个那么ans可以变小。
我们可以用网络流来判断,建边如下:
ins(st,i,1),//表示起点向行连一条边
ins(j+n,ed,1),//表示列向终点连一条边
如果i,j这个点的值<=ansins(i,j+n,1)
限制流量为一,就保证了不会选到在同行或者同列的店
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define inf 0x7fffffff/3 
using namespace std;
const int N=600;
int n,m,k;
int map[N][N];
int l,r=0,st,ed;
struct node{
	int x,y,z,next,other;
}sa[N*N];int len=0,first[N];
void ins(int x,int y,int z)
{
    len++;
    sa[len].x=x;
    sa[len].y=y;
    sa[len].z=z;
    sa[len].next=first[x];
    first[x]=len;
    sa[len].other=len+1;
     
    len++;
    sa[len].x=y;
    sa[len].y=x;
    sa[len].z=0;
    sa[len].next=first[y];
    first[y]=len;
    sa[len].other=len-1;
}
int list[100005],h[100005],head,tail;
bool bt()//宽搜只是为了构建h数组 
{
    memset(h,0,sizeof(h));h[st]=1; //出发点的层次为1
    list[1]=st;head=1;tail=2; //宽搜
    while(head!=tail)
    {
        int x=list[head];
        for(int k=first[x];k!=-1;k=sa[k].next)
        {
            int y=sa[k].y;
            if(  sa[k].z>0 &&  h[y]==0  )//a[k].c>0让多次构图成为可能
            {
                // x >y这条边还有流量,并且 y没有访问过
                h[y]=h[x]+1;   //y作为x的下一层
                list[tail++]=y;
            }
        }
        head++;
    }
    if(h[ed]>0) return true;//如果最后能到ed返回true,否则返回false
    else return false;
}
int findans(int x,int f)//函数值等于:带着“期待流量”f从x出发,最后得到的“实际流量”s。 
{
    if(x==ed) return f; //x如果是终点,那么当前所带的期待目标流量都可以完成 
    int s=0,t;
    for(int k=first[x];k!=-1;k=sa[k].next) // 尝试通过所有孩子结点分散任务
    {
        int y=sa[k].y;  
        if( sa[k].z>0 && h[y]==(h[x]+1) && s<f )//a[k].c>0表示x->y这条边还有流量,且y是x的下一层,且“实际流量”<“期望流量”还没有满
        { 
            s+=(  t=findans(  y  , min(sa[k].z,f-s)  )  ); //从y出发,而附带的“期望流量”是多少呢?; 
            sa[k].z-=t;sa[ sa[k].other ].z+=t; //及时修改边的流量,且同时增加反向边的流量
        }
    }
    if(s==0)h[x]=0;//如果x出发没有流量,x从此不可走
    return s;
}
bool check(int x)
{
	memset(first,-1,sizeof(first));
	len=0;
	for(int i=1;i<=n;i++)ins(st,i,1);
	for(int j=1;j<=m;j++)ins(j+n,ed,1);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(map[i][j]<=x)
			ins(i,j+n,1);
		}
	}
	int ans=0;
	while(bt()!=false)
	{
		ans+=findans(st,inf);
	}
	if(ans>=n-k+1) return true;
	else return false;
}
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	st=0;ed=n+m+1;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&map[i][j]);r=max(map[i][j],r);
		}
	}
	l=0;
	int mid,an;
	while(l<r)
	{
		mid=(l+r)>>1;
		if(check(mid)==true) r=mid,an=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
}



考虑可再生能源出力不确定性的商业园区用户需求响应策略(Matlab代码实现)内容概要:本文围绕“考虑可再生能源出力不确定性的商业园区用户需求响应策略”展开,结合Matlab代码实现,研究在可再生能源(如风电、光伏)出力具有不确定性的背景下,商业园区如何制定有效的需求响应策略以优化能源调度和提升系统经济性。文中可能涉及不确定性建模(如场景生成与缩减)、优化模型构建(如随机规划、鲁棒优化)以及需求响应机制设计(如价格型、激励型),并通过Matlab仿真验证所提策略的有效性。此外,文档还列举了大量相关的电力系统、综合能源系统优化调度案例与代码资源,涵盖微电网调度、储能配置、负荷预测等多个方向,形成一个完整的科研支持体系。; 适合人群:具备一定电力系统、优化理论和Matlab编程基础的研究生、科研人员及从事能源系统规划与运行的工程技术人员。; 使用场景及目标:①学习如何建模可再生能源的不确定性并应用于需求响应优化;②掌握使用Matlab进行商业园区能源系统仿真与优化调度的方法;③复现论文结果或开展相关课题研究,提升科研效率与创新能力。; 阅读建议:建议结合文中提供的Matlab代码实例,逐步理解模型构建与求解过程,重点关注不确定性处理方法与需求响应机制的设计逻辑,同时可参考文档中列出的其他资源进行扩展学习与交叉验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值