NYOJ 973 天下第一(最长路判环)
来源:互联网 发布:免费手机视频编辑软件 编辑:程序博客网 时间:2024/04/30 22:34
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=973
题目大意:给你n种武功,每两种武功都可以相互转化,但是有转化率f, 每次必须从一开始转化, 中间有武功转化不了, 后面的就不能在转化了, 问你能否可以无限增加转化。
在做这道题以前做了和这道题一样的一道题, 所以我认为很快就能AC了, 但是这道题我还是弄了一天还是没能AC。来讲一下让我很是郁闷的问题吧。 这道题可以用最短路判环(spfa只需稍微变一下)来做,也可以用直接深搜来做。我的最初想法就是深搜来做。我上一道题就是用深搜做的,我就开始写了, 然后就是各种WA, 后来搞到后台数据找到一组错误的输出, 然后就是各种改, 最终还是WA, 没办法了, 我就写了一个spfa, 然后就AC了, 看来正解还是spfa, 现在我还是不明白我以前的为什么错。所以发个博客记录一下, 以免在出现这种情况。同时想让路过的大牛给解释一下。
下面是代码
AC的
#include<stdio.h>#include<string.h>#include<vector>#include<queue>#include<algorithm>using namespace std;const int maxn = 500 + 10;struct Edge{ int v; double f; Edge(int i, double j) : v(i), f(j) {}};vector<Edge> G[maxn];double d[maxn];int cnt[maxn];bool inq[maxn];bool spfa(int s, int n){ queue<int> Q; memset(inq, false, sizeof(inq)); memset(d, 0, sizeof(d)); memset(cnt, 0, sizeof(cnt)); d[s] = 1.0; inq[s] = true; Q.push(s); while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = false; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i].v; double ff = G[u][i].f; if(d[v]<d[u]*ff) { d[v] = d[u]*ff; if(!inq[v]) { Q.push(v); inq[v] = true; if(++cnt[v] >= n) return true; } } } } return false;}int main(){ int T, n, m, a, b; double ff;// freopen("Input.txt", "r", stdin);// freopen("O.txt", "w", stdout); scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for(int i = 0; i <= n; i++) G[i].clear(); while(m--) { scanf("%d%lf%d", &a, &ff, &b); G[a].push_back(Edge(b, ff)); } if(spfa(1, n)) puts("Yes"); else puts("No"); } return 0;}
WA的
#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>using namespace std;const int maxn = 500 + 10;int vis[maxn];int pre[maxn];struct Info{ int to; double f; Info(int i, double j) :to(i), f(j) {}};vector<Info> G[maxn];bool dfs(int rt, int u, double ans){ vis[u] = -1; for(int i = 0; i < G[u].size(); i++) { Info x = G[u][i]; int v = x.to; pre[v] = pre[u]; double Ans = ans * x.f; if(Ans == 0) continue; if(v==rt) { if(Ans>1.0) return true; } if(!vis[v] && dfs(rt, v, Ans)) return true; } vis[u] = 1; return false;}int main(){ int T, n, m;// freopen("Input.txt", "r", stdin);// freopen("O.txt", "w", stdout); scanf("%d", &T); while(T--) { memset(pre, -1, sizeof(pre)); scanf("%d%d", &n, &m); for(int i = 0; i <= n; i++) G[i].clear(); while(m--) { int a, b; double ff; scanf("%d%lf%d", &a, &ff, &b); G[a].push_back(Info(b, ff)); } bool flag = false; pre[1] = 1; for(int i = 1; i <= n; i++) { memset(vis, 0, sizeof(vis)); if(pre[i]==1 && dfs(i, i, 1.0)) { flag = true; break; } } if(flag) printf("Yes\n"); else printf("No\n"); } return 0;}
这是深搜的wa的代码,唯一一组出现错误测试数据33肿武功, 93种转化 应该输出Yes 如果直接暴搜就会超时33 9330 0.3 3223 0.9 618 0.9 2113 0.9 1421 1.2 1128 0 2432 0.5 2923 1.1 1226 0.5 87 0.1 126 1.4 3329 0.9 3012 1.3 610 0.4 3233 0.2 69 0.5 1224 1.7 224 1 113 0.5 11 0.8 220 0 75 1.7 1513 1.1 167 0.7 2130 0.6 3118 0.9 1028 1.7 1431 0.8 3327 1.6 1529 0.4 1926 0.9 223 0.8 520 0.4 629 1 711 1.6 3130 0.6 1718 1.5 2321 1.2 3221 0.4 166 0.3 2013 0 337 0.3 3214 0.2 47 0.3 2814 0.7 917 0.9 281 0.1 193 0.9 711 0.8 2933 1.9 109 0.7 137 0.3 175 0.1 2118 0 169 1.7 511 0.7 1020 1.2 1413 0.5 2229 0.3 2312 0 211 0.1 1629 1.3 251 0.7 296 0.9 254 0.3 827 1.5 1411 0.5 174 1.8 3332 1.4 2611 0.2 3230 0.2 729 1.6 518 0.2 68 0.4 2823 1.8 3317 1.3 2316 0.5 1322 0.3 2625 0.7 222 1.6 3216 1.6 2633 1.8 819 0.2 2928 0.5 1323 1.8 248 0.7 519 1.1 2327 0.9 516 0.7 2219 1.3 928 1.9 2631 0.8 625 1 16
0 1
- NYOJ 973 天下第一(最长路判环)
- nyoj 973 天下第一
- NYOJ 973 天下第一
- nyoj 973 天下第一
- nyoj 973 天下第一
- NYOJ973天下第一_最长路判环
- NYOJ-973-天下第一(SPFA判环)
- nyoj--973--天下第一(SPFA判断负环)
- NYOJ 973 天下第一 判断有没有环存在
- 天下第一
- nyoj-984-最长回文
- 天下第一 973 (SPFA模板求生成环 好题)
- 天下第一文
- 天下第一,唯我独尊!
- nyoj973天下第一
- NYOJ973_天下第一
- NYOJ 132 最长回文字符串
- 最长公共子序列 nyoj
- 函数调用运算符
- Mac OS 修改ROOT账户密码
- IIS String was not recognized as a valid DateTime报错
- c语言中常用转换函数
- 时间的处理
- NYOJ 973 天下第一(最长路判环)
- 【Java】ArrayList<String>转化为String数组问题
- Android 系统稳定性 - ANR(二)
- 传者-通往牛掰的路
- neutron network types(2)
- Struts2生成验证码
- Android 系统稳定性 - ANR(三)
- 进程间通信--信号量详解及编程实例
- Spark Pipe使用方法(外部程序调用方法)