博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ural 1004 FLOYD最小环问题
阅读量:6955 次
发布时间:2019-06-27

本文共 3012 字,大约阅读时间需要 10 分钟。

题目大意: 给出一些双向边, 求图中的一个最小环, 当u-v被选中时, v-u不能被选, 按顺序输出这个最小环, n<=100

无解则输出。

题目既然要求最小环,数据范围还这么小, 容易联想到FLOYD, 并且这里是双向边也没有什么关系, 因为只能选一条, 但题目比较麻烦的地方就是要输出这个环,

我的处理好像和机房的人不一样。。。。。

我想到的办法是对于每一个i -> j的路径, 记下最优的中间点, 再记下最小环中的最大序号点, 和最小环中的floyd的那一条路径的起点和终点, 递归输出。
开始一直WA#2, 一开始以为是我的FLOYD和网上主流的FLOYD不一样, 然而好像我的FLOYD那个细节地方貌似无关紧要, 然后突然发现有个BUG!!!! 因为我的最小环记下的路径是前k-1个点为中间点更新后的答案, 所以一种诡异的情况就是第k次恰好可以更新掉我记下的路径, 那么我输出的答案会有两个k点(手动滑稽。。。。)所以我就做了两遍, 先做出最小环再跑一遍FLOYD就ok

好像还可以用个vector来更新答案, 不过没我的方便hhhh

贴代码-----

#include 
#include
const int N = 100 + 10;const int oo = 1e8 + 1e7 + 7e5;#define min(a, b) a < b? a : b#define rep(i, s, t) for(int i = s; i <= t; ++i)int G[N][N], p[N], Mid, x, y, top;int n, m, a[N][N], f[N][N], Ans[N];void init() { top = 0; Mid = 0, x = 0, y = 0; rep(i, 0, n) p[i] = 0; rep(i, 0, n) rep(j, 0, n) a[i][j] = f[i][j] = oo, G[i][j] = 0;}void dfs(int i, int j) { if(a[i][j] == f[i][j]) { if(!p[i]) Ans[++top] = i, p[i] = 1; if(!p[j]) Ans[++top] = j, p[j] = 1; return ; } dfs(i, G[i][j]), dfs(G[i][j], j);}int main() {#ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); freopen("res.out", "w", stdout);#endif while(1) { scanf("%d", &n); if(n == -1) break; scanf("%d", &m); init(); rep(i, 1, m) { int u, v, w; scanf("%d%d%d", &u, &v, &w); a[u][v] = a[v][u] = min(a[u][v], w); f[u][v] = f[v][u] = a[u][v]; } rep(i, 0, n) a[i][i] = f[i][i] = 0; int Res = oo; rep(k, 1, n) { rep(i, 1, k-1) rep(j, 1, k-1) if(i ^ j) if(a[k][i] + a[j][k] + f[i][j] < Res) Res = a[k][i] + a[j][k] + f[i][j]; rep(i, 1, n) rep(j, 1, n) if(f[i][k] + f[k][j] < f[i][j]) { f[i][j] = f[i][k] + f[k][j]; G[i][j] = k; } } if(Res >= oo) { puts("No solution."); continue; } bool flag = 0; rep(i, 1, n) rep(j, 1, n) f[i][j] = a[i][j], G[i][j] = 0; rep(k, 1, n) { rep(i, 1, k-1) { rep(j, 1, k-1) if(i ^ j) if(a[k][i] + a[j][k] + f[i][j] == Res) { Mid = k, x = i, y = j; flag = 1; break; } if(flag) break; } if(flag) break; rep(i, 1, n) rep(j, 1, n) if(f[i][k] + f[k][j] < f[i][j]) { f[i][j] = f[i][k] + f[k][j]; G[i][j] = k; } } p[Mid] = 1, Ans[++top] = Mid; dfs(x, y); rep(i, 1, top) printf("%d%c", Ans[i], i^top? ' ':'\n'); } return 0;}

看起来很长吧, 其实思路很清晰的。。。。。相信你们也不会来看我的这么丑的代码

转载于:https://www.cnblogs.com/pbvrvnq/p/8530154.html

你可能感兴趣的文章
文件比较 增量 更新 系统发布 增量更新
查看>>
我的友情链接
查看>>
Android游戏开发的开源框架
查看>>
C#类对象转换成XML
查看>>
Docker-registry + GlusterFS
查看>>
Centos7安装Docker-1.9.1
查看>>
RabbitMQ入门
查看>>
主机屋使用后感
查看>>
exchange2010 DAG备份
查看>>
learning python on the way
查看>>
Windows Server 2012 文件服务器群集
查看>>
常用SQL语句(1)
查看>>
关于JSP表单的一些技巧和经验
查看>>
解决 SQL 注入的另类方法
查看>>
10款常用Java测试工具
查看>>
身份证号验证
查看>>
j2ee学习方法摘要
查看>>
go任务调度2(linux的cron调用)
查看>>
主辅dns服务器的配置
查看>>
mysql-proxy实现读写分离
查看>>