当前位置: 首页 > news >正文

有没有专门做包装设计的网站ssc网站建设交流群

有没有专门做包装设计的网站,ssc网站建设交流群,做企业网站还有钱挣吗,做网站apache如何Floyd算法是一种对所有点对最短路径算法、多源最短路径算法#xff0c;以此计算能得到图中每一对节点之间的最短路径。Floyd不仅可以用来求多源最短路#xff0c;也可以用于解决传递闭包问题。 算法思想#xff1a; Floyd求最短路径用的是“从小图到全图”的动态规划思想以此计算能得到图中每一对节点之间的最短路径。Floyd不仅可以用来求多源最短路也可以用于解决传递闭包问题。 算法思想 Floyd求最短路径用的是“从小图到全图”的动态规划思想定义状态dp[k][i][j]i、j、k都为节点编号范围为1~n。状态dp[k][i][j]表示在包含1~k点的子图上点对i、j的最短路径。当从子图1~k-1扩展成子图1~k时状态转移方程为 dp[k][i][j]min(dp[k-1][i][j], dp[k-1][i][k]dp[k-1][k][j]); dp[k-1][i][j]是不考虑经过k点的旧的i到j的路径dp[k-1][i][k]dp[k-1][k][j]是考虑经过k点的新的i到j的路径较小者就是新的dp[k][i][j]。 当k从1逐步扩展到n时最后得到的dp[n][i][j]就是点对i、j之间的最短路径长度。若i、j是直连的初值dp[0][i][j]就是边长若不直连初值为无穷大。 在具体实现时我们利用滚动数组技巧将dp[][][]缩成dp[][]因为dp[k][][]只和dp[k-1][][]有关所以可以省略掉k这一维。由于k是动态规划子问题的“阶段”即k是从点1开始逐步扩大到n的所以k循环必须在i、j循环的外层。 关键代码 void floyd() {for (int k 0; k n; k) // 不能将最外层的k循环放到内层这会导致结果出错{for (int i 0; i n; i){for (int j 0; j n; j){if(d[i][k] ! INF d[k][j] ! INF d[i][k] d[k][j] d[i][j]){d[i][j] d[i][k] d[k][j]; // 找到更短的路径}}}} } 或者 void floyd() {for (int k 0; k n; k) // 不能将最外层的k循环放到内层这会导致结果出错{for (int i 0; i n; i){for (int j 0; j n; j){d[i][j] min(d[i][j], d[i][k]d[k][j]);}}} } 算法特征 1能一次性求得所有节点之间的最短距离。 2效率不高时间复杂度为O(n^3)n为节点数量。 3用邻接矩阵存储最合适因为Floyd算法求的是所有点对之间的最短距离本身就需要n*n的存储空间。 4可用于负权边可以判断负环。因为Floyd基于动态规划思想而非贪心思想所以即使图中存在负权边也可以保证从局部最优可以推导到全局最优。如果图中存在负环那么每在这个负环上绕一圈总长度就更小从而使得能与这个负环连通的点对的最短距离都将成为负无穷大。而Floyd算法很容易判断负环只要在算法运行过程中出现任意dp[i][i]0就说明有负环。因为dp[i][i]是从i出发经过其他中转点绕一圈回到自己的最短路径如果小于0即存在负环。 算法的常见应用场景以及例题 1图的规模n300。时间复杂度O(n^3)限制了图的规模。 2可能多次查询不同点对之间的最短路径。 例题hdu 1385 题意非常简单的模板题该题需要输出具体的路径点。 思路求最短路就是最简单的Floyd模板我们讨论打印具体路径的方法用path[][]记录路径path[i][j]u表示起点为i终点为j的最短路径从i出发下一个点是u。一个完整的路径是从s出发查询path[s][j]u找到下一个点为u然后从u出发查询path[u][j]v下一个点是v重复这个操作直到最后到达终点j。路径的具体计算见代码。 代码 #include iostream #include cstdio #include cstring #include cstring using namespace std;const int maxn5000; const int INF100000000;int n; int node[maxn]; int dist[maxn][maxn]; int path[maxn][maxn];void floyd() {for(int i1;in;i)//初始化 有一种后驱的感觉for(int j1;jn;j)path[i][j]j;for(int k1;kn;k)for(int i1;in;i)for(int j1;jn;j){int tempdist[i][k]dist[k][j]node[k];if(dist[i][j]temp){dist[i][j]temp;path[i][j]path[i][k];}if(dist[i][j]temp){if(path[i][j]path[i][k])path[i][j]path[i][k];}} }int main() {int a,be,en;while(scanf(%d,n)n){for(int i1;in;i)for(int j1;jn;j){scanf(%d,a);if(a!-1) dist[i][j]a;else dist[i][j]INF;}for(int i1;in;i) scanf(%d,node[i]);floyd();int kcase0;while(1){if(kcase!0) printf(\n);kcase;scanf(%d%d,be,en);if(be-1en-1) break;printf(From %d to %d :\n,be,en);printf(Path: );printf(%d,be);int tempbe;while(temp!en){printf(--%d,path[temp][en]);temppath[temp][en];}printf(\n);printf(Total cost : %d\n,dist[be][en]);}}return 0; } 3问题的解决和中转点有关。这是Floyd算法的核心思想算法用DP方法遍历中转点计算最短路径。 例题洛谷P1119 灾后重建 个人题解戳这 4路径在“兜圈子”一个点可能多次经过。这是Floyd算法的特点其他路径算法都不行。 例题洛谷P1613 跑路 个人题解戳这 5解决传递闭包问题。传递闭包是离散数学的概念给定一个集合以及若干对元素之间的传递关系传递闭包问题是求所有元素之间的传递连通关系。例如包括3个元素的集合{a,b,c}给定传递关系a-bb-c那么可以推导出a-c。在图论中可以把传递闭包问题转换为给定一个有向图其中有n个点和m条边求所有点对之间的连通性关系。传递闭包是“多源”路径问题。 例题1hdu1704 Rank 题意有m场比赛每场比赛由两人决胜负。已知一些比赛的成绩现在要查询任意两人之间的胜负情况要求输出有多少个查询的胜负是不能被确定的。在本题中我们认为胜负关系具有传递性即若A赢了BB赢了C那么得出A赢了C。n,m 500。 思路把参赛人员和胜负关系建模为一个有向图有向边A-B表示A赢了B。然后使用Floyd算法求解传递闭包矩阵矩阵中等于1代表能确定胜负为0代表不能确定。统计Floyd后矩阵中为0的数量即可。本题n500比较小简单优化即可通过。如果n1000则需要使用bitset优化减少一层循环。bitset是一种类似数组的数据结构它的每个元素用1b存储只能是0或者1。使用了bitset后Floyd算法在传递闭包的特殊情况下时间复杂度可以优化到接近O(n^2)。 代码 #include bits/stdc.h using namespace std; #define endl \n typedef long long ll; typedef unsigned long long ull; const int maxn 1e3 10; const int INF 0x3fffffff; const int mod 1000000007; int dis[maxn][maxn]; int n, m;void floyd() {for (int k 1; k n; k) {for (int i 1; i n; i) {if (!dis[i][k])continue;for (int j 1; j n; j) {if (!dis[k][j])continue;dis[i][j] 1;}}} }void solve() {cin n m;for (int i 1; i n; i) { // 初始化for (int j 1; j n; j) {dis[i][j] (i j);}}for (int i 0; i m; i) {int u, v;cin u v;dis[u][v] 1;}floyd();int ans 0;for (int i 1; i n; i) {for (int j i 1; j n; j) {if (dis[i][j] 0 dis[j][i] 0) {ans;}}}cout ans endl; }int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout fixed;cout.precision(18);int t;cin t;while (t--)solve();return 0; } 下面也给出bitset优化的代码bitset的作用是省去了最后一层j的循环改用位运算或的方式对整个bitset数组的每一位一次性计算 #include bits/stdc.h using namespace std; #define endl \n typedef long long ll; typedef unsigned long long ull; const int maxn 1e3 10; const int INF 0x3fffffff; const int mod 1000000007; bitsetmaxn dis[maxn]; int n, m;void floyd() {for (int k 1; k n; k) {for (int i 1; i n; i) {if (!dis[i][k])continue;dis[i] | dis[k];}} }void solve() {cin n m;for (int i 1; i n; i) { // 初始化for (int j 1; j n; j) {dis[i][j] (i j);}}for (int i 0; i m; i) {int u, v;cin u v;dis[u][v] 1;}floyd();int ans 0;for (int i 1; i n; i) {for (int j i 1; j n; j) {if (dis[i][j] 0 dis[j][i] 0) {ans;}}}cout ans endl; }int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout fixed;cout.precision(18);int t;cin t;while (t--)solve();return 0; } 例题2POJ1127 题意给出n条线段线段相交即连通判断任意两条线段是否连通 思路首先用计算几何的算法求出线段相交将线段之间的相交构建成二维矩阵就可以转换成传递闭包问题了用Floyd求出所有线段之间的连通性。 代码 #include cstdio #include iostream #include cmath using namespace std; const int maxn 20; const int maxm 1e4 10; double EPS 1e-10;// 考虑误差的加法运算 double add(double a, double b) {if(abs(a b) EPS * (abs(a) abs(b)))return 0;return a b; }// 二维向量结构体 struct P {double x, y;P() {}P(double x, double y){this-x x;this-y y;}void input(){cin x y;}P operator (P p){return P(add(x, p.x), add(y, p.y));}P operator - (P p){return P(add(x, -p.x), add(y, -p.y));}P operator * (double d){return P(x * d, y * d);}double dot(P p) // 内积{return add(x * p.x, y * p.y);}double det(P p) // 外积{return add(x * p.y, -y * p.x);} };// 判断两条直线是否平行 bool isParallel(P p1, P p2, P q1, P q2) {return (p1 - p2).det(q1 - q2) 0; }// 判断点q是否在线段p1p2上 bool on_seg(P p1, P p2, P q) {return (p1 - q).det(p2 - q) 0 (p1 - q).dot(p2 - q) 0; }// 计算直线p1p2与直线q1q2的交点 P intersection(P p1, P p2, P q1, P q2) {// return p1 (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));double t ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));P x ((p2 - p1) * t);return p1 x; }int n, m; P p[maxn], q[maxn]; // 一个线段的起点和终点 int A[maxm], B[maxm]; // 题目要询问哪些木棍的连接情况 bool G[maxn][maxn]; // 线段之间的相连关系void floyd() {for (int k 1; k n; k){for (int i 1; i n; i){for (int j 1; j n; j){G[i][j] | (G[i][k] G[k][j]);}}} }void solve() {// 先判断所有的线段两两之间是否有直接的公共点for (int i 1; i n; i){G[i][i] true;for (int j 1; j i; j){if(i j) continue;// 判断线段i和线段j是否有公共点if(isParallel(p[i], q[i], p[j], q[j])){ // 平行时我们检查任一端点是否在另一条线段上来判断两条线段是否有公共点G[i][j] G[j][i] on_seg(p[i], q[i], p[j]) || on_seg(p[i], q[i], q[j]) || on_seg(p[j], q[j], p[i]) || on_seg(p[j], q[j], q[i]);}else{P cross intersection(p[i], q[i], p[j], q[j]);G[i][j] G[j][i] on_seg(p[i], q[i], cross) on_seg(p[j], q[j], cross);}}}// 通过floyd算法判断任意两条线段之间是否连通传递闭包问题floyd();// 输出结果for (int i 1; i m; i){G[A[i]][B[i]] ? cout CONNECTED\n : cout NOT CONNECTED\n;} }int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin n;while(n ! 0){for (int i 1; i n; i){p[i].input();q[i].input();// cout p[i].x p[i].y q[i].x q[i].y endl;}for (int i 1; ; i){int a, b;cin a b;if(a 0 b 0)break;m i;A[i] a;B[i] b;// cout A[i] B[i] endl;}solve();cin n;}return 0; }
http://www.zqtcl.cn/news/687525/

相关文章:

  • 石家庄城乡建设厅网站牡丹江百度推广
  • 网站建设源代码 费用事件网站推广
  • 购物网站开发文献综述潮汕网站建设
  • 做五金生意什么网站做比较好网站建设市场规模
  • 网站跟app的区别是什么网络搭建结构图
  • 淘宝网站怎么做视频教程山西推广型网站开发
  • 杭州开发网站2018主流网站建设语言
  • 杂志社网站建设方案书响应式网站服务
  • 青岛网站开发建设农村建设有限公司网站
  • 做水晶接单在哪个网站接php做购物网站怎么样
  • 网站内部结构优化网页设计网站搭建
  • 杭州公司建设网站网络营销是一种什么营销
  • 事业单位网站建设费科目定西市小企业网站建设
  • 温州网站推广哪家好网站开发所遵循的
  • 没有网站做APP公司logo设计公司logo设计
  • 网站建设在哪个软件下做中国最大的现货交易平台
  • 西宁做网站公司电话加强局网站建设
  • 佛山做企业网站公司做贸易做个外贸网站有必要吗
  • 南昌制作网站的公司wordpress 分享到插件
  • 大型网站怎样做优化PHP站长工具怎么用
  • 响应式模板网站建设营销型网站建设怎么收费
  • 夺宝网站开发全网seo优化电话
  • 宁夏建设工程招标投标信息管理中心网站广告多的网站
  • c 网站做死循环北京响应式的网站设计
  • 手机门户网站建设莱芜雪野湖国际会议中心酒店
  • 男人女人做那事网站vue加wordpress
  • 古色古香 网站模板西安企业黄页网站
  • 上海企业网站怎么建设交互设计网站有哪些
  • 企业网站设计与制作开发一款游戏app需要多少钱
  • 贵阳网站方舟网络北京手机网站制作