UVA 11721 Instant View of Big Bang(负环)
2015-11-24 02:44
351 查看
题意:
n<=1000,m<=2000的有向图,无自环,无重边,求所有能到达负环的点集合,升序输出,不存在输出impossible
分析:
−−不知道为啥正向搜一直RE,把oj测爆了也没找到
考虑逆向思考问题,负环能到达的点,构建逆图,逆图的负环当然也是原图的负环
然后找到负环去搜所有能到达的点,标记保证复杂度,问题解决
复杂度O(nm)
代码:
n<=1000,m<=2000的有向图,无自环,无重边,求所有能到达负环的点集合,升序输出,不存在输出impossible
分析:
−−不知道为啥正向搜一直RE,把oj测爆了也没找到
考虑逆向思考问题,负环能到达的点,构建逆图,逆图的负环当然也是原图的负环
然后找到负环去搜所有能到达的点,标记保证复杂度,问题解决
复杂度O(nm)
代码:
// // Created by TaoSama on 2015-11-22 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> #include <ctime> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e3 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; const int M = 2e3 + 10; int n, m; struct Edge { int v, nxt, c; } edge[M]; int head , cnt; void addEdge(int u, int v, int c) { edge[cnt] = (Edge) {v, head[u], c}; head[u] = cnt++; } bool in , vis ; int dp , num , negative; void dfs(int u) { vis[u] = true; for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(vis[v]) continue; dfs(v); } } void spfa(int s) { queue<int> q; q.push(s); memset(dp, 0x3f, sizeof dp); memset(in, false, sizeof in); memset(num, 0, sizeof num); in[s] = num[s] = 1; dp[s] = 0; while(q.size()) { int u = q.front(); q.pop(); in[u] = false; for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(vis[v]) continue; if(dp[v] > dp[u] + edge[i].c) { dp[v] = dp[u] + edge[i].c; if(!in[v]) { in[v] = true; if(++num[v] >= n) { negative = true; dfs(v); } q.push(v); } } } } } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\in.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); int kase = 0; while(t--) { cnt = 0; memset(head, -1, sizeof head); scanf("%d%d", &n, &m); while(m--) { int u, v, c; scanf("%d%d%d", &u, &v, &c); addEdge(v, u, c); //reversing graph, cycle to point } negative = false; memset(vis, false, sizeof vis); for(int i = 0; i < n; ++i) { if(vis[i]) continue; spfa(i); } if(!negative) { printf("Case %d: impossible\n", ++kase); continue; } printf("Case %d:", ++kase); for(int i = 0; i < n; ++i) if(vis[i]) printf(" %d", i); puts(""); } return 0; }
相关文章推荐
- CSU1307 并查集+SPFA
- 最短路径 -- spfa
- 单源最短路深度分析
- USACO/butter 3.2.6
- hdu 1596 find the safest road(spfa算法)
- MZ Training 2014 #8 F题
- MZ Training 2014 #4 B题
- [网络流24题 #18]分配问题
- [网络流24题 #18]分配问题
- 收益最大
- acm-hdu2544解题报告
- hdu2112 spfa
- POJ 3037 Skiing SPFA
- POJ 3255 Roadblocks 次短路 SPFA
- poj 1511 Invitation Cards
- poj 1724 ROADS 邻接表+优先队列+spfa()
- hdu 1224 Free DIY Tour
- hdu2544最短路——spfa
- hdu1548A strange lift——最短路(迪杰斯特拉,spfa)。bfs(队列。数组)
- poj 1201 interval 差分约束/贪心+线段树区间更新