POJ ~ 3259 ~ Wormholes (BellmanFord和SPFA模板)
2018-01-28 23:57
369 查看
题意:一个famer有一些农场,这些农场里面有一些田地,田地里面有一些虫洞,田地和田地之间有路双向路,虫洞有这样的性质: 时间倒流。问你这个农民能不能看到他自己,也就是说,有没有这样一条路径,能利用虫洞的时间倒流的性质,让这个人能在这个点出发前回去,这样他就是能看到他自己。
输入n个点m条田地之间的路,w个虫洞。
思路:有负环输出YES,没负环输出NO。
交POJ会CE,换一下万能头就好了。
队列优化BellmanFord(SPFA):
最坏情况复杂度O(n*m),一般比这个快的多
BellmanFord:
复杂度O(n*m)
输入n个点m条田地之间的路,w个虫洞。
思路:有负环输出YES,没负环输出NO。
交POJ会CE,换一下万能头就好了。
队列优化BellmanFord(SPFA):
最坏情况复杂度O(n*m),一般比这个快的多
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 5; const int INF = 0x3f3f3f3f; struct Edge { int from, to, dist; //起点,终点,距离 Edge(int u, int v, int w):from(u), to(v), dist(w) {} }; struct SPFA { int n, m; //结点数,边数(包括反向弧) vector<Edge> edges; //边表。edges[e]和edges[e^1]互为反向弧 vector<int> G[MAXN]; //邻接表,G[i][j]表示结点i的第j条边在edges数组中的序号 bool vis[MAXN]; //是否在队列中 int d[MAXN]; //Bellman-Ford int p[MAXN]; //上一条弧 int cnt[MAXN]; //进队次数 void init(int n) { this->n = n; edges.clear(); for (int i = 0; i <= n; i++) G[i].clear(); } void add_edge(int from, int to, int dist) { edges.push_back(Edge(from, to, dist)); m = edges.size(); G[from].push_back(m - 1); } bool spfa(int s) { for (int i = 0; i <= n; i++) d[i] = INF; memset(vis, 0, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); d[s] = 0; vis[s] = true; queue<int> Q; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = false; for (int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; if (d[u] < INF && d[e.to] > d[u] + e.dist) { d[e.to] = d[u] + e.dist; p[e.to] = G[u][i]; if (!vis[e.to]) { Q.push(e.to); vis[e.to] = true; if (++cnt[e.to] > n) return false;//有负环 } } } } return true;//没有负环 } }; SPFA solve; int main e52c () { int T; scanf("%d", &T); while(T--) { int n, m, w; scanf("%d%d%d", &n, &m, &w); solve.init(n); while(m--) { int u, v, t; scanf("%d%d%d", &u, &v, &t); solve.add_edge(u, v, t); solve.add_edge(v, u, t); } while (w--) { int u, v, t; scanf("%d%d%d", &u, &v, &t); solve.add_edge(u, v, -t); } if (!solve.spfa(1)) printf("YES\n");//没负环 else printf("NO\n");//有负环 } return 0; }
BellmanFord:
复杂度O(n*m)
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 5; const int INF = 0x3f3f3f3f; struct Edge { int from, to, dist; //起点,终点,距离 Edge(int u, int v, int w):from(u), to(v), dist(w) {} }; struct BellmanFord { int n, m; //结点数,边数(包括反向弧) vector<Edge> edges; //边表。edges[e]和edges[e^1]互为反向弧 vector<int> G[MAXN]; //邻接表,G[i][j]表示结点i的第j条边在edges数组中的序号 bool vis[MAXN]; //是否在队列中 int d[MAXN]; //Bellman-Ford int p[MAXN]; //上一条弧 int cnt[MAXN]; //进队次数 void init(int n) { this->n = n; edges.clear(); for (int i = 0; i <= n; i++) G[i].clear(); } void add_edge(int from, int to, int dist) { edges.push_back(Edge(from, to, dist)); m = edges.size(); G[from].push_back(m - 1); } bool bellman_ford(int s) { for (int i = 0; i <= n; i++) d[i] = INF; d[s] = 0; for (int k = 0; k < n - 1; k++)//迭代n-1次 { bool flag = false; for (int i = 0; i < m; i++)//检查每条边 { Edge& e = edges[i]; if (d[e.from] < INF && d[e.to] > d[e.from] + e.dist) { flag = true; d[e.to] = d[e.from] + e.dist; p[e.to] = i; } } if (!flag) break;//只要某一次没relax,说明最短路径已经查找完毕,或者部分点不可达,可以跳出 } for (int i = 0; i < m; i++) { Edge& e = edges[i]; if (d[e.from] < INF && d[e.to] > d[e.from] + e.dist) return false;//有负环 } return true;//没有负环 } }; BellmanFord solve; int main() { int T; scanf("%d", &T); while(T--) { int n, m, w; scanf("%d%d%d", &n, &m, &w); solve.init(n); while(m--) { int u, v, t; scanf("%d%d%d", &u, &v, &t); solve.add_edge(u, v, t); solve.add_edge(v, u, t); } while (w--) { int u, v, t; scanf("%d%d%d", &u, &v, &t); solve.add_edge(u, v, -t); } if (!solve.bellman_ford(1)) printf("YES\n");//没负环 else printf("NO\n");//有负环 } return 0; } /* 2 3 3 1 1 2 2 1 3 4 2 3 1 3 1 3 3 2 1 1 2 3 2 3 4 3 1 8 */ //Answer:NO,YES
相关文章推荐
- Poj 3259 Wormholes 负环判断 SPFA & BellmanFord
- POJ 3259-Wormholes (Bellman-Ford&&SPFA) (模板题)
- poj 3259 Wormholes(spfa) (spfa模板)
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- POJ 3259 Wormholes(SPFA+邻接表)
- Wormholes (poj 3259 SPFA || Bellman_Ford 判负环)
- Poj 3259 Wormholes【SPFA判断负权回路】
- POJ-3259 Wormholes(SPFA)
- poj_3259 Wormholes(bollman-ford / SPFA)
- poj 3259 Wormholes(spfa 判环)
- poj 3259 Wormholes(spfa)
- POJ 3259 Wormholes(SPFA 判负环)
- Poj 3259 Wormholes判断负权回路(spfa模板题)
- POJ 3259 Wormholes (SPFA&&BellMan Ford)
- POJ 3259 Wormholes(SPFA)
- poj 3259 Wormholes 【SPFA&&推断负环】
- POJ训练计划3259_Wormholes(Bellman-Ford)(SPFA)
- Poj 3259 Wormholes(spfa判负环)
- poj 3259 Wormholes (spfa判负环)
- poj 3259 Wormholes(spfa)