poj 3259 Wormholes 图论 最短路 判负环
2015-11-11 23:06
387 查看
题目
题目链接:http://poj.org/problem?id=3259题目来源:《挑战》练习题
简要题意:NN个点,MM条无向边权为时间,WW个单向虫洞可以返回过去,问能不能在出发前回到起点。
数据范围:1⩽N⩽500;1⩽M⩽2500;1⩽W⩽2001 \leqslant N \leqslant 500;\quad 1 \leqslant M \leqslant 2500;\quad 1 \leqslant W \leqslant 200
题解
看了样例才理解了题目。绕一圈回到起点是个环咯,这个环还是负的,那就是要判负环咯。
实现
可以用Bellman-Ford或者SPFA写,神奇的是加个dis[0] < 0的判断可以快很多141ms→16ms141ms\to 16ms。
因为SPFA比较快,我就写了它。
代码
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int N = 505; const int M = 6005; const int INF = 0x3f3f3f3f; struct Edge { int to, nxt, c; Edge(int to, int nxt, int c) : to(to), nxt(nxt), c(c) {} Edge() {} }; int head ; Edge e[M]; void addEdge(int from, int to, int c, int cnt) { e[cnt] = Edge(to, head[from], c); head[from] = cnt; } void init(int n) { for (int i = 0; i < n; i++) head[i] = -1; } bool vis ; int cntv ; int dis ; bool spfa(int st, int n) { memset(vis, 0, sizeof vis); memset(cntv, 0, sizeof cntv); memset(dis, INF, sizeof dis); queue<int> q; q.push(st); vis[st] = true; dis[st] = 0; while (!q.empty()) { int cur = q.front(); q.pop(); vis[cur] = false; for (int i = head[cur]; ~i; i = e[i].nxt) { Edge &ee = e[i]; if (ee.c + dis[cur] < dis[ee.to]) { dis[ee.to] = ee.c + dis[cur]; if (dis[0] < 0 || ++cntv[ee.to] == n) return true; if (!vis[ee.to]) vis[ee.to] = true, q.push(ee.to); } } } return false; } int main() { int t, n, m, w, u, v, c; scanf("%d", &t); while (t--) { int cnt = 0; scanf("%d%d%d", &n, &m, &w); init(n); for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &c); u--, v--; addEdge(u, v, c, cnt++); addEdge(v, u, c, cnt++); } for (int i = 0; i < w; i ++) { scanf("%d%d%d", &u, &v, &c); u--, v--; addEdge(u, v, -c, cnt++); } puts(spfa(0, n) ? "YES" : "NO"); } return 0; }
相关文章推荐
- Hadoop1.x程序升级到Hadoop2.x需要的依赖库,Cannot initialize Cluster.Please check your configuration for ma
- block定义详解
- PHP动态创建属性的get和set方法
- markdown语法
- 更改hosts后还是无法使用Google,Facebook,Twitter等服务怎么办?
- 信号槽
- Swift学习笔记
- lua开发--模板渲染
- 20151111,微软11月11日发布12个安全补丁
- struts2常量配置的方式
- mysql 中 isnull 和 ifnull 判断字段是否为null
- hive学习笔记(1)
- Android LayoutAnimation
- 《编写有效用例》阅读笔记一
- AJAX—核心XMLHttpRequest对象
- QQ好友列表(处理头部控件的点击)viewForHeaderInSection:
- Struts2应用开发步骤
- 搭建前端框架
- css样式表
- 学生——成绩表2.3