【BZOJ1001】狼抓兔子

【题目描述】

现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:  左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.

【输入格式】

第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M

【输出格式】

输出一个整数,表示参与伏击的狼的最小数量.

【分析】

看一眼就知道这一道典型的最小割问题,但是数据太大了,传统解法会导致超时。

我才知道有平面图最小割转最短路的方法==。(参见2008年周冬神牛论文)

尼玛以后邻接表加边再也不用LRJ的了,害得我MLE了无数次......

 

  1 #include <cstdlib>
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <vector>
  7 #include <queue> 
  8 const int Max=1001*1001*2;//最大点个数 
  9 const int INF=~0U>>2;
 10 using namespace std;
 11 //边结构体 
 12 struct edge{int to,w;};
 13 struct node
 14 {
 15        int dist,num;
 16        //按照距离大小排序 
 17        bool operator <(const node &b)const
 18        {
 19             return dist>b.dist;
 20        }
 21 };
 22 int s,t,n,m;//源汇点
 23 int dist[Max]; 
 24 vector<edge>G[Max]; 
 25 priority_queue<node>Q;
 26 
 27 void init();
 28 void AddEdge(int u,int v,int w);
 29 int dijkstra(int sta);
 30 
 31 int main()
 32 {
 33     //文件操作
 34     //freopen("data.txt","r",stdin);
 35     //freopen("me.out","w",stdout);
 36     
 37     init();//读入数据 
 38     //for (int i=0;i<G[13].size();i++) printf("%d \n",Edges[G[13][i]].w);
 39     
 40     printf("%d\n",dijkstra(s));
 41     return 0;
 42 }
 43 //读入+建图 
 44 void init()
 45 {
 46      int i,j;
 47      //读入长宽,共有(n-1)*(m-1)*2个顶点
 48      scanf("%d%d",&n,&m);
 49      s=0;t=(n-1)*(m-1)*2+1;//设定源汇点 
 50      //一行总共有2*(m-1)个节点 
 51      for (i=1;i<=n;i++)//读入横边 
 52      for (j=1;j<m;j++)
 53      {
 54          int w;
 55          scanf("%d",&w);
 56          if (i==1) AddEdge(j*2,t,w);//连最上面的点与汇点
 57          else if (i==n) AddEdge((i-2)*2*(m-1)+2*j-1,s,w);//最下面的点与源点相连 
 58          else AddEdge((i-2)*2*(m-1)+2*j-1,(i-1)*2*(m-1)+2*j,w);//上下顶点相连 
 59      }
 60      for (i=1;i<n;i++)//读竖边 
 61      for (j=1;j<=m;j++)
 62      {
 63          int w;
 64          scanf("%d",&w);
 65          if (j==1) AddEdge((i-1)*2*(m-1)+2*j-1,s,w);//最左边的连源点 
 66          else if (j==m) AddEdge((i-1)*2*(m-1)+2*(j-1),t,w);//最右边的连汇点
 67          else  AddEdge((i-1)*2*(m-1)+2*(j-1),(i-1)*2*(m-1)+2*j-1,w);//竖边左右相连 
 68      } 
 69      for (i=1;i<n;i++)//读对角线 
 70      for (j=1;j<m;j++)
 71      {
 72          int w;
 73          scanf("%d",&w);
 74          AddEdge((i-1)*2*(m-1)+2*j-1,(i-1)*2*(m-1)+2*j,w);//对角线加边 
 75      } 
 76      return;
 77 }
 78 //加无向边 
 79 void AddEdge(int u,int v,int w)
 80 {
 81      G[u].push_back((edge){v,w});
 82      G[v].push_back((edge){u,w});
 83 }
 84 int dijkstra(int sta)
 85 {
 86     int i;
 87     for (i=0;i<=t;i++)
 88     dist[i]=INF;
 89     
 90     Q.push((node){0,s});
 91     while(Q.size())
 92     {
 93         node u=Q.top();Q.pop();if(u.dist>dist[u.num])continue;
 94         if(u.num==t) return u.dist;
 95         for (i=0;i<G[u.num].size();i++)
 96         {
 97             int ncost=u.dist+G[u.num][i].w;
 98             if(ncost<dist[G[u.num][i].to])
 99             {
100                 dist[G[u.num][i].to]=ncost;
101                 Q.push((node){ncost,G[u.num][i].to});
102             }
103         }
104     }
105 }
View Code

 

 

 

转载于:https://www.cnblogs.com/hoskey/p/3751687.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的文件内容,本文将详细解析“飞行弹道仿真”的核心知识点,主要涉及MATLAB编程环境下的弹道仿真实现过程。 ### 弹道仿真概述 弹道仿真是一种通过数学模型来预测导弹、炮弹等飞行器在空中飞行轨迹的技术。在军事、航天等多个领域都有着广泛的应用。对于弹道仿真的研究不仅有助于提升武器系统的精确度,还能帮助科研人员更好地理解空气动力学原理以及飞行器的动力特性。 ### MATLAB环境下弹道仿真的实现 #### 1. **初始化参数** 在代码中,作者首先对一系列变量进行了初始化处理。这些变量包括但不限于:质量(`m`), 速度(`V`), 高度(`H`)等关键物理量。此外,还定义了一些常量如重力加速度(`g`)、空气密度(`rho_air`)等。 #### 2. **地面高度分布设定** 通过设定地面高度随距离变化的函数(`x_d` 表示水平距离,`H_d` 表示对应的高度),可以模拟不同的地形特征。这里使用了一个分段函数来表示地面高度的变化情况。 #### 3. **动态方程与运动方程** - **动态方程**:描述了导弹受到的外力作用(推力、阻力、升力)以及重力对其运动状态的影响。 - 推力(`P`)、阻力(`X`)、升力(`Y`)等参数被用于计算导弹的速度和角度变化。 - 通过积分运算更新速度、角度等状态量。 - **运动方程**:描述了导弹在三维空间中的位置变化情况。 - 包括水平方向速度(`equ4_Kinematic_x`)、垂直方向速度(`equ5_Kinematic_y`)以及姿态角(`equ6_Kinematic_Theta`)的变化。 - 这些方程同样通过积分方法进行求解。 #### 4. **控制律设计** 控制律设计是确保导弹按照预定轨迹飞行的关键环节。例如,代码中采用了简单的PID控制策略来调整导弹的姿态角。具体地: - `k_phi` 和 `k_phidiff` 分别代表比例系数和微分系数。 - 通过调整这些系数的值,可以优化导弹的飞行性能,使其更加稳定且能够准确跟踪目标。 #### 5. **数值积分方法** 为了求解动态方程与运动方程,文中采用了一种数值积分方法(`integral_to_next`)。该方法可以近似计算出导弹在下一时刻的状态量(速度、角度等)。虽然具体的实现细节没有给出,但通常这类方法基于欧拉法或者更高级的龙格-库塔法等。 ### 结论 本文通过对“飞行弹道仿真”这一主题的深入探讨,不仅详细介绍了如何使用MATLAB进行弹道仿真,而且还重点讲解了其中涉及到的重要概念和技术细节,如地面高度分布设定、动态方程与运动方程、控制律设计以及数值积分方法等。对于希望深入了解弹道仿真技术的研究者来说,本文提供了丰富的参考资料和实施指南。通过这样的仿真研究,不仅可以提高导弹等飞行器的设计精度,还能为未来航空航天技术的发展提供强有力的支持。
项目:使用AngularJs编写的简单 益智游戏(附源代码)  这是一个简单的 javascript 项目。这是一个拼图游戏,也包含一个填字游戏。这个游戏玩起来很棒。有两个不同的版本可以玩这个游戏。你也可以玩填字游戏。 关于游戏 这款游戏的玩法很简单。如上所述,它包含拼图和填字游戏。您可以通过移动图像来玩滑动拼图。您还可以选择要在滑动面板中拥有的列数和网格数。 另一个是填字游戏。在这里你只需要找到浏览器左侧提到的那些单词。 要运行此游戏,您需要在系统上安装浏览器。下载并在代码编辑器中打开此项目。然后有一个 index.html 文件可供您修改。在命令提示符中运行该文件,或者您可以直接运行索引文件。使用 Google Chrome 或 FireFox 可获得更好的用户体验。此外,这是一款多人游戏,双方玩家都是人类。 这个游戏包含很多 JavaScript 验证。这个游戏很有趣,如果你能用一点 CSS 修改它,那就更好了。 总的来说,这个项目使用了很多 javascript 和 javascript 库。如果你可以添加一些具有不同颜色选项的级别,那么你一定可以利用其库来提高你的 javascript 技能。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值