ZJOI 2009 狼和羊的故事 网络流

探讨了如何通过添加最短篱笆实现羊狼和谐共存的问题,利用网络流算法中的最小割思想解决这一挑战。

题目:

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

思路:

一开始没往网络流想,想了一些乱七八糟的找规律方法,无果。看了标签才想到做法......

将每个格子当做一个点,源点S向所有1连边,所有2向汇点T连边,其边权均为INF;然后0或1向相邻的0或2的点连边,其边权均为1;这样问题转化为使源点不能到达汇点的最小割。权当复习一遍Dinic吧。。。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>

#define For(i,j,k) for(int i = j;i <= (int)k;i++)
#define Forr(i,j,k) for(int i = j;i >= (int)k;i--)
#define Set(i,j) memset(i, j, sizeof(i)) 
#define pb push_back

using namespace std;

const int N = 110, M = N * N;
const int d[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

int n, m, cnt = 1, Map[N][N], id[N][N];

struct Edge{
	int to, flow, cap;
};

struct Dinic{
	vector<int> G[M];
	int S, T, e;
	int dis[M], cur[M];
	bool vis[M];
	Edge E[M<<4];

	void Add(int x, int y, int f){
		E[e] = (Edge){y, 0, f}, G[x].pb(e++);
		E[e] = (Edge){x, 0, 0}, G[y].pb(e++);
	}

	bool BFS(){
		Set(vis, 0);
		queue<int> q;
		q.push(S);
		vis[S] = 1, dis[S] = 0;
		while(!q.empty()){
			int h = q.front(); q.pop();
			For(i,0,G[h].size() - 1){
				Edge& s = E[G[h][i]];
				if(vis[s.to] || s.flow == s.cap) continue;
				vis[s.to] = 1, dis[s.to] = dis[h] + 1;
				q.push(s.to);
			}
		}
		return vis[T];
	}

	int DFS(int h, int f){
		if(h == T) return f;
		int sum = 0;
		for(int &i = cur[h];i < G[h].size() && sum < f;i++){
			Edge& s = E[G[h][i]];
			int t;
			if(dis[h] + 1 == dis[s.to] && (t = DFS(s.to, min(s.cap - s.flow, f - sum)))){
				sum += t;
				s.flow += t;
				E[G[h][i] ^ 1].flow -= t;
			}
		}
		return sum;
	}

	int Maxflow(int s, int t){
		S = s, T = t;
		int Ans = 0;
		while(BFS()){
			Set(cur, 0);
			Ans += DFS(S, 1e9);
		}
		return Ans;
	}

}S;

int main(){
	scanf("%d%d", &n, &m);
	For(i,1,n) For(j,1,m) scanf("%d", &Map[i][j]), id[i][j] = ++cnt;
	For(i,1,n) For(j,1,m){
		if(Map[i][j] == 1) S.Add(0, id[i][j], 1e9);
		else if(Map[i][j] == 2){
			S.Add(id[i][j], 1, 1e9);
			continue;
		}
		For(v,0,3){
			int x = i + d[v][0], y = j + d[v][1];
			if(Map[x][y] != 1) S.Add(id[i][j], id[x][y], 1);
		}
	}
	printf("%d\n", S.Maxflow(0, 1));
	return 0;
}


内容概要:本文系统整理了《微软面试100题完整版(含解析+备考指南)2026最新求职资源》,涵盖算法编程、逻辑思维、计算机基础、系统设计与工程实践、职场综合五大核心题型,共100道高频原题,均来自微软近十年真实面试题库,剔除过时内容,新增AI工程应用、轻量化系统设计等2026年前沿考点。每道题目配有详细解题思路与考察要点,覆盖数据结构、动态规划、位运算、网络协议、数据库事务、微服务架构、高并发设计等关键技术领域,并包含逻辑推理、工程排查、产品权衡等综合素质题目,全面适配微软海内外各岗位面试需求。此外,文章还提供分层刷题策略、地域差异化备考建议及完整资源获取路径,助力求职者高效通关初面、复面与终面。; 适合人群:准备应聘微软的应届毕业生、1-5年工作经验的技术岗从业者(如软件开发、算法、测试、数据、运维等),以及计划投递微软海外岗位的求职者;尤其适合缺乏系统面试准备、希望提升解题思维与工程表达能力的人群。; 使用场景及目标:①针对微软技术面试中的算法题进行专项突破,掌握最优解法与代码规范;②训练逻辑思维与系统设计能力,应对高阶岗位考察;③准备终面综合问题,提升职场素养与岗位匹配度表达;④根据国内/海外不同考点调整复习重点,实现精准备考。; 阅读建议:此资源以真题为核心,强调解题思路而非死记硬背,建议按“分类刷题—总结模板—模拟手撕—复盘优化”流程学习,重点关注代码边界处理、复杂度优化与中英文表达逻辑,结合自身背景补充项目复盘与系统设计练习,全面提升面试实战能力。
内容概要:本文围绕永磁同步电机(PMSM)的二阶线性自抗扰矢量控制系统展开深入研究,重点实现了基于Simulink的系统建模仿真。研究采用二阶线性自抗扰控制(LADRC)策略,结合扩张状态观测器(ESO)对系统内部动态外部扰动进行实时估计与前馈补偿,有效提升了电机在负载突变、参数摄动等复杂工况下的转速控制精度、动态响应速度与系统鲁棒性。文中详细构建了电流环与转速环的双闭环矢量控制架构,系统分析了控制器关键参数的设计方法、观测器带宽的整定原则以及整体系统的稳定性条件,并通过大量仿真实验验证了所提出控制方案相较于传统PI控制在抗干扰能力、响应性能鲁棒性方面的显著优越性。; 适合人群:具备自动控制理论、电机控制原理、现代控制理论等相关专业知识,熟悉Simulink/Matlab仿真环境,且有一定工程实践经验的电气工程、自动化、控制科学与工程等领域的硕士/博士研究生、科研人员及从事高性能电机驱动系统开发的工程技术人员。; 使用场景及目标:①为高等院校科研机构提供先进电机控制算法的教学案例与科研实验平台,深化对自抗扰控制(ADRC)理论的理解;②为企业在高性能伺服驱动、新能源汽车电驱系统、工业自动化等领域的下一代控制器研发提供可靠的技术参考、仿真验证方案原型设计基础;③帮助研究人员系统掌握ADRC的核心思想、设计流程及其在高精度运动控制系统中的具体工程实现方法。; 阅读建议:学习者应具备扎实的自动控制与电机学理论基础及Simulink建模能力,建议结合韩京清教授的经典ADRC文献进行原理性学习,深入理解ESO的观测机理与TD的安排机制。在仿真实践中,应动手调试控制器带宽、观测器增益等核心参数,对比分析不同扰动工况(如突加负载、转速指令跳变)下的系统响应曲线,以直观感受控制性能的差异。为进一步深化研究,可将该仿真模型与硬件在环(HIL)测试平台或实际电机实验平台对接,完成从算法设计、仿真验证到物理实现的完整闭环验证流程。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值