MNNUACM--暑假训练之二分图

本文深入探讨了信息技术领域的核心算法及其在不同场景的应用,包括数据挖掘、机器学习、人工智能等多个方面,旨在为读者提供全面的技术视角。

Problem 1001(HDU 1083 Courses)

题目大意:

给你p门课程和n个学生,一个学生可以选0门,1门,或者多门课程,现在要求一个由p个学生组成的集合,满足下列2个条件:

1.每个学生选择一个不同的课程

2.每个课程都有不同的代表

如果满足,就输出YES


思路:

二分图的最大匹配;

学生和课程分别为定点集合vx vy

把学生和他喜欢的的课程连一条边;

#include<iostream>
using namespace std;

const int N=500;

int vx,vy;
int graph[N][N];
int link[N];
bool visit[N];

bool dfs(int u)
{
	for(int i=1;i<=vy;i++)
	{
		if(graph[u][i] && !visit[i])
		{
			visit[i]=true;
			if(link[i]==-1 || dfs(link[i]))
			{
				link[i]=u;
				return true;
			}
		}
	}
	return false;
}
 

int hungary()
{
	int max_match=0;

	for(int i=1;i<=vx;i++)
	{
		memset(visit,false,sizeof(visit));

		if(dfs(i))
			max_match++;
	}
	return max_match;
}

int main()
{
	int cases;
	scanf("%d",&cases);
	while(cases--)
	{
		memset(graph,0,sizeof(graph));
		memset(link,-1,sizeof(link));

		int p,n;
		scanf("%d%d",&p,&n);
		
		vx=p;
		vy=n;
		int stu_num;
		int tmp;

		/*Input & Structure Graph*/
		for(int i=1;i<=p;i++)
		{
			scanf("%d",&stu_num);
			for(int j=1;j<=stu_num;j++)
			{
				scanf("%d",&tmp);
				graph[i][tmp]=1;//
			}
		}
		printf("%s\n", hungary() == p ? "YES" : "NO"); 
	}
	return 0;
}



Problem 1002(hdu 1002 Machine Schedule)

题目大意:

有k个任务,A和B两种机器,两种机器分别有vx和vy种模式;

每个任务可以分别在两种机器的某一种模式上运行,问及其转换模式最少几次可以完成k个任务;


思路:

二分的最小顶点覆盖问题;

最小顶点覆盖=最大匹配数

	#include<iostream>
	using namespace std;

	const int N=500;

	int vx,vy;
	int graph[N][N];
	int link[N];
	bool visit[N];

	bool dfs(int u)
	{
		for(int i=1;i<=vy;i++)
		{
			if(graph[u][i] && !visit[i])
			{
				visit[i]=true;
				if(link[i]==-1 || dfs(link[i]))
				{
					link[i]=u;
					return true;
				}
			}
		}
		return false;
	}
 

	int hungary()
	{
		int max_match=0;

		for(int i=1;i<=vx;i++)
		{
			memset(visit,false,sizeof(visit));

			if(dfs(i))
				max_match++;
		}
		return max_match;
	}

	int main(int k)
	{
		while(~scanf("%d",&vx),vx)
		{
			memset(graph,0,sizeof(graph));
			memset(link,-1,sizeof(link));
			scanf("%d%d",&vy,&k);

			/*Input & Structure Graph*/
			for(int i=1;i<=k;i++)
			{
				int a,b,t;
				scanf("%d%d%d",&t,&a,&b);
				graph[a][b]=1;
			}
			printf("%d\n",hungary());
		}
		return 0;
	}


problem 1003(HDU 1281 棋盘游戏)

中文题 意思就不用说了;

思路:

首先求出二分图最大匹配,

再依次枚举点,去掉该店如果最大匹配数减少了,就是重要点;

#include<iostream>
using namespace std;

const int N=500;

int vx,vy;
int graph[N][N];
int link[N];
bool visit[N];

bool dfs(int u)
{
	for(int i=1;i<=vy;i++)
	{
		if(graph[u][i] && !visit[i])
		{
			visit[i]=true;
			if(link[i]==-1 || dfs(link[i]))
			{
				link[i]=u;
				return true;
			}
		}
	}
	return false;
}
 

int hungary()
{
	int max_match=0;
	memset(link,-1,sizeof(link));
	for(int i=1;i<=vx;i++)
	{
		memset(visit,false,sizeof(visit));

		if(dfs(i))
			max_match++;
	}
	return max_match;
}

int main(int i)
{
    int numcase=1;
    while(~scanf("%d%d",&vx,&vy))
    {
        int k;
        int a[10500],b[10500];    
        memset(graph,0,sizeof(graph));

        scanf("%d",&k);
        for(i=0;i<k;i++)
        {
            scanf("%d%d",&a[i],&b[i]);
            graph[a[i]][b[i]]=1;
        }

        int maxmatch=hungary();
        int temp;
        int c=0;
        for(i=0;i<k;i++)
        {
            graph[a[i]][b[i]]=0;
            temp=hungary();
            if(temp<maxmatch)
                c++;
           graph[a[i]][b[i]]=1;
        }
        printf("Board %d have %d important blanks for %d chessmen.\n",numcase++,c,maxmatch);
    }
    return 0;
}

Problem 1004(HDU Uncle Tom's Inherited Land*)

题目大意:

有个n*m的土地,给出土地中k个1*1的pond的坐标(题目描述中的图b);

先要要出售这块土地,但是规定的允许出售的土地为1*2或者2*1的方块并且不能使pond(题目描述中的图c);

问能出售的方块土地最多有多少快;


思路:

这题建图会比较困难,不过仔细想应该可以想的出来;

代码有用到vector,不懂的去看看相关资料;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define N 10010

vector <int> graph[N];
int n,m,k;
bool used[N];
bool visited[110][110];
int link[N];

bool dfs(int u) 
{
    for(int i=0;i<graph[u].size();i++) 
	{
        int v=graph[u][i];
        if(!used[v]) 
		{
            used[v]=true;
            if(link[v]==-1 ||dfs(link[v])) 
			{
                link[v]=u;
                return true;
            }
        }
    }
    return false;
}


int hungary()
 {
    int max_match=0;
    memset(link,-1,sizeof(link));
    for(int i=1;i<=n*m;i++) 
	{
        memset(used,false,sizeof(used));
		if(dfs(i))
			max_match++;
    }
    return max_match;
}

int main(int i,int j) 
{
    int u,v;
    while(scanf("%d%d",&n,&m),n&&m) 
	{
		/*Initial*/
        for(int i=1; i<=n*m; i++)
			graph[i].clear();
		memset(visited,false,sizeof(visited));

        scanf("%d",&k);
        for(i=1; i<=k; i++) 
		{
            scanf("%d%d",&u,&v);
            visited[u][v]=true;//标记ponds
        }

		/*Structure Graph*/
        for(i=1;i<=n;i++) 
		{
            for(j=1;j<=m;j++) 
			{
                if(visited[i][j])//如果是ponds 跳过
					continue;

                if(i+1<=n && !visited[i+1][j]) 
				{
                    graph[(i-1)*m+j].push_back( i*m+j );
                    graph[i*m+j].push_back( (i-1)*m+j );
                }

                if(j+1<=m && !visited[i][j+1]) 
				{
                    graph[(i-1)*m+j].push_back( (i-1)*m+j+1 );
                    graph[(i-1)*m+j+1].push_back( (i-1)*m+j );
                }
            }
        }

        int max_num=hungary();

        printf("%d\n",max_num/2);

		int x1,x2,y1,y2;

        for(i=1;i<=n*m;i++)
		{
            if(link[i]!=-1 && link[link[i]]!=-1 ) 
			{
                if(!(y1=i%m))
					y1=m;
				x1=(i-y1)/m+1;

                y2=link[i]%m;
                if(!(y2=link[i]%m))
					y2=m;
                x2=(link[i]-y2)/m+1;

                link[i]=link[link[i]]=-1;
                printf("(%d,%d)--(%d,%d)\n",x1,y1,x2,y2);
            }
        }
        puts("");
    }
    return 0;
}


problem 1005(HDU 1068 Girls and Boys)

这里求的最大点独立集,但是要注意的一点是,给出的是同学之间的亲密关系,并没有指出哪些是男哪些是女,所以求出的最大匹配数
要除以2才是真正的匹配数

#include<iostream>
using namespace std;

const int N=501;

int graph[N][N];
int match[N];
bool visit[N];
int vx;
int vy;

bool dfs(int x)
{
	for(int y=0;y<vy;y++)
	{
		if(graph[x][y] && !visit[y])
		{
			visit[y]=true;
			if(match[y]==-1 || dfs(match[y]) )
			{
				match[y]=x;
				return true;
			}
		}
	}
	return false;
}

int hungary()
{
	int max_match=0;
	memset(match,-1,sizeof(match));

	for(int x=0;x<vx;x++)
	{
		memset(visit,false,sizeof(visit));
		if(dfs(x))
			max_match++;
	}
	return max_match;
}

int main()
{
    int a,b,t;
    while(~scanf("%d",&vx))
    {
        memset(graph,0,sizeof(graph));
        vy=vx;
		int a,b,t;
        for(int i=0;i<vx;i++)
        {
            scanf("%d: (%d)",&a,&b);
            while(b--)
            {
                scanf("%d",&t);
                graph[a][t]=1;
            }
        }
        printf("%d\n",vx-hungary()/2);
    }
    return 0;
}


problem 1008(hdu 1533 Going Home)

题目大意:

给定一个N*M的地图,地图上有一定数量的m(代表人)和H(代表房子),两者数量相等;

要求求出把所有m移动到H的位置上总距离最小为多少;


思路:

用最优二分匹配或者最小费用最大流都能做,觉得用最优二分匹配会简单一些;

建图把m和H分别作为二分图的两个顶点集合vx和vy,求出两两之间的距离,用km算法求出最优匹配;

要注意的是,要求距离的最短,而km求的是最大匹配值,所以建图的时候距离要取反;

#include<iostream>
#include<cmath>
using namespace std;

const int MAX=105;
const int inf=1<<30;

int n,lack;
int map[MAX][MAX]; 
char maps[MAX][MAX];
int dx[MAX],dy[MAX]; 
int link[MAX];
bool visx[MAX],visy[MAX]; 

bool DFS(int v)
{
    visx[v]=true;
    for(int i=0;i<n;i++)
    {
        if(visy[i])
            continue;
        int t=dx[v]+dy[i]-map[v][i];
        if(!t)
        {
            visy[i]=true;
            if(link[i]==-1||DFS(link[i]))
            {
                link[i]=v;
                return true;
            }
        }
        else 
            if(t<lack)
                lack=t;
    }
    return false;
}

void KM()
{
    int i,j;
    memset(dx,0,sizeof(dx));
    memset(dy,0,sizeof(dy));
    memset(link,-1,sizeof(link));
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
            if(map[i][j]>dx[i])
                dx[i]=map[i][j];
    }
    for(i=0;i<n;i++)
    {
        while(true)
        {
            memset(visx,0,sizeof(visx));
            memset(visy,0,sizeof(visy));
            lack=0x7fffffff;
            if(DFS(i))
                break;
            for(j=0;j<n;j++)
            {
                if(visx[j])
                    dx[j]-=lack;
                if(visy[j])
                    dy[j]+=lack;
            }
        }
    }
}

int main(int i,int j,int k,int l)
{
    int row,col,ans,numi,numj;
    while(scanf("%d%d",&row,&col)&&(row+col))
    {
		/*Initial*/
        n=ans=numi=numj=0;
        memset(link,-1,sizeof(link));
        memset(map,0,sizeof(map));

		/*Input*/
        for(i=0;i<row;i++)
        {
            scanf("%*c");
            for(j=0;j<col;j++)
            {
                scanf("%c",&maps[i][j]);
                if(maps[i][j]=='m')
                    n++;
            }
        }
		/*Structure Graph*/
		/*±ßȨֵ±äΪ¸ºÈ¨£¬Çó³ö×î´óÆ¥ÅäÖµ¼´Îª×îС¾àÀë×ܺÍ*/

        for(i=0;i<row;i++) 
        {
            for(j=0;j<col;j++)
            {
                if(maps[i][j]=='m')
                {
                    for(k=0;k<row;k++)
                    {
                        for(l=0;l<col;l++)
                        {
                            if(maps[k][l]=='H')
                                map[numi][numj++]=-(abs(k-i)+abs(l-j)); //±ßΪ¸ºÈ¨Öµ
                        }
                    }
                    numi++;
                    numj=0;
                }
            }
        }
        KM();
        int ans=0;    
        for(i=0;i<n;i++)
        {
            if(link[i]!=-1)
                ans+=map[link[i]][i];
        }

        printf("%d\n",-ans);
    }
    return 0;
}


内容概要:本文介绍了一种用于电磁暂态(EMT)研究的第四类全变流器型风力发电系统的通用Simulink仿真模型,旨在构建一个能够准确反映实际风电系统动态特性的简化通用模型。该模型涵盖了风力机、传动链、发电机、全功率变流器及其控制策略等关键组成部分,重点突出系统在电网故障、风速波动等复杂工况下的动态响应能力,适用于风电并网电磁暂态分析、新型电力系统稳定性评估及高比例可再生能源接入场景的研究。模型设计兼顾准确性与仿真效率,便于研究人员快速搭建和调试,推动风电系统建模与控制技术的发展; 适合人群:具备一定电力系统理论基础和MATLAB/Simulink仿真能力,从事新能源发电、电力电子变换、风电并网控制及相关方向的研究生、科研人员及工程技术人员; 使用场景及目标:①开展风电系统在电网扰动下的电磁暂态仿真分析;②研究全功率变流器风电机组的动态行为与控制特性;③支撑新型电力系统中高渗透率风电接入的稳定性与电能质量评估,服务于学术研究、课程教学与工程项目前期仿真验证; 阅读建议:建议读者结合文中提供的模型结构与参数设置,在Simulink环境中动手复现并调试仿真模型,通过设置不同运行工况(如三相短路、低电压穿越、风速突变等)观察系统响应,深入理解全变流器风电机组的建模方法、控制逻辑与动态特性,进而拓展应用于更复杂的多机并网或综合能源系统仿真场景。
内容概要:本文探讨了Hash算法在芯片行业,特别是网络处理器(NPU)中的性能优化实践,聚焦于如何通过硬件流水线设计实现纳秒级高速哈希查找。文章分析了传统软件哈希方案在高带宽场景下的局限性,提出基于硬件描述语言或高层次综合(HLS)的设计方法,采用CRC32等硬件友好型哈希函数、并行多路哈希、流水线化解耦以及双端口存储结构等核心技术,实现低延迟、无阻塞的数据包处理。通过C++风格的HLS代码示例,展示了从算法选择到资源优化的完整硬件加速逻辑,并深入剖析了循环展开、位宽控制、内存映射和流水线调度等关键实现细节。最后展望了可编程交换机、P4语言支持及TCAM与哈希混合架构等未来发展方向。; 适合人群:具备数字电路基础、熟悉Verilog/SystemVerilog或HLS的芯片设计工程师,以及从事网络芯片、FPGA加速、高性能路由设备研发的技术人员(工作年限1-5年为宜);也适合对硬件加速算法感兴趣的研究人员。; 使用场景及目标:①掌握如何将哈希算法高效映射到硬件逻辑中以满足线速转发需求;②理解流水线设计、资源约束优化、读写冲突规避等在实际芯片项目中的应用;③为开发高性能网络处理器中的流表/路由表查找单元提供技术参考与实现范例。; 阅读建议:学习时应结合HLS工具(如Xilinx Vitis HLS)进行代码仿真与综合,重点关注#pragma指令对硬件结构的影响,并对比不同哈希算法在资源占用与时序表现上的差异,深入理解“空间换时间”的硬件优化本质。
内容概要:本文系统研究了基于粒子群优化(PSO)、灰狼优化(GWO)、鲸鱼优化(WOA)、哈里斯鹰优化(HHO)、蜣螂优化(DBO)和麻雀搜索算法(SSA)六种智能优化算法在无人机三维路径规划中的应用,并在Matlab平台上实现了相应的仿真代码。研究构建了复杂的三维地形与障碍物环境模型,设计了包含路径长度、飞行时间、能耗及安全性等多维度的成本函数,通过定义合理的适应度函数与飞行约束条件,对各类算法的路径搜索能力、收敛速度与规划质量进行了全面对比分析。通过仿真实验验证了各算法在静态复杂环境下的性能表现,旨在为实际无人机任务中优化算法的选择提供科学依据和技术支持。; 适合人群:具备一定Matlab编程基础,从事智能优化算法、无人机路径规划、自动化控制及相关领域研究的研究生、科研人员或工程技术人员。; 使用场景及目标:① 掌握主流群智能优化算法在无人机三维路径规划中的建模与实现方法;② 对比分析不同算法在相同复杂环境下的性能差异,为算法选型提供量化依据;③ 为后续研究动态环境路径规划、多无人机协同任务分配等问题奠定理论与技术基础; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点关注适应度函数的设计、障碍物规避策略的实现以及多目标成本函数的权衡机制,同时可通过调整参数设置或引入新型优化算法进行扩展实验,以深化对算法性能的理解与实际应用能力。
内容概要:本文研究了复杂威胁环境下基于多段杜宾斯(Dubins)路径的多无人机协同路径规划问题,提出了一种结合无人机运动学约束与优化算法的协同规划方法。通过Matlab平台实现了路径规划算法的建模与仿真,构建了包含障碍物、禁飞区及动态威胁因素的复杂环境模型,采用优化策略对多无人机系统的飞行路径进行全局协同优化,确保各无人机在满足Dubins路径连续性和曲率约束的前提下,实现任务最优或近优完成。该方法有效解决了多机路径间的冲突规避问题,提升了路径的安全性、可行性和整体效率,具有较强的工程应用价值。; 适合人群:具备一定编程基础和自动化、航空航天、智能无人系统等相关学科背景的科研人员及研究生,尤其适合从事路径规划、多智能体协同控制、智能优化算法研究的专业人士。; 使用场景及目标:①应用于军事侦察、灾害救援、边境巡检、区域监控等多无人机协同作业的实际任务场景;②为复杂环境下多智能体系统的避障、协同决策与路径优化提供算法支持与技术参考;③辅助研究人员复现算法模型,开展进一步的创新性研究与性能对比分析。; 阅读建议:此资源以Matlab代码实现为核心,强调理论与仿真实践相结合,建议读者在掌握Dubins路径基本原理的基础上,结合所提供的代码进行参数调试与仿真实验,深入理解协同优化机制与算法收敛特性,从而提升对多无人机系统路径规划问题的整体认知与研究能力。
内容概要:本文提出一种基于灰狼优化算法(GWO)改进互补集合经验模态分解(CEEMDAN)的混合储能系统风电功率平抑策略。通过GWO智能优化CEEMDAN的关键参数,显著提高了对非平稳风电功率信号的分解精度与自适应性,有效解决了传统方法中存在的模态混叠与残余噪声问题。在此基础上,结合混合储能系统(如锂电池与超级电容)的动态特性,设计合理的功率分配机制,将分解后的高低频分量分别交由适宜的储能单元响应,充分发挥各储能器件的优势,实现对风电功率高频波动与低频变化的协同平抑。研究通过Matlab平台进行算法编程与系统建模,开展仿真验证,结果表明该策略能显著降低储能系统的综合损耗,提升风电并网功率的平滑度与稳定性,延长储能设备使用寿命。; 适合人群:具备电力系统自动化、新能源并网技术、信号处理或智能优化算法等相关专业知识,熟悉Matlab/Simulink仿真工具,从事风电并网控制、储能系统优化或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于风电场实际运行中,优化储能系统参与功率平抑的控制策略;②为解决高比例新能源接入带来的电网波动问题提供先进的信号分解与功率分配技术方案;③作为智能优化算法(GWO)与先进信号处理技术(CEEMDAN)在能源系统交叉应用的研究范例。; 阅读建议:读者应重点结合提供的Matlab代码,深入理解GWO算法的寻优流程、CEEMDAN的改进实现细节以及混合储能功率分配的逻辑设计,建议动手复现整个仿真过程,通过调整参数和对比不同工况,以全面掌握该策略的性能优势与应用要点。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值