luogu解题报告:P1262间谍网络【代码量惊人】【图论/强连通缩点】
2016-10-23 19:40
357 查看
题目见https://www.luogu.org/problem/show?pid=1262
然后就开始考验码农功了。。。。。对象的思想得到了运用。。
注:代码用vscode完成,果然优美2333.
分析
这个题一眼看上去并不难,似乎bfs就能解决问题,但事实上bfs只能解决第一问。第二问如何解决呢?首先要明确:强连通分量内如果有一个间谍被捕,所有人就会被捕,代价是其中所需金额最少的一个。因此可以进行强连通缩点,变成一个DAG。不难发现,金额最少就是DAG中所有入度为0的点的金额和。因为这些点非取不可,且取了就可以控制所有人。然后就开始考验码农功了。。。。。对象的思想得到了运用。。
示例代码
#include <bits/stdc++.h> using namespace std; //#define DEBUG /*basis of graph*/ class graph { public: struct p { int to, next; } edge[9005]; int head[3003], top; int rank[3003]; int rd[3003]; graph() { memset(head, 0, sizeof head); memset(rd, 0, sizeof rd); memset(rank, 127/3, sizeof rank); top = 0; } void edit_rank(int i, int j) { rank[i] = j; } void push(int i, int j) { edge[++top].to = j; edge[top].next = head[i]; head[i] = top; rd[j]++; } }; /* vars */ graph basic, reversed, solved; int n, p, r; int grp = 0; /*kosaraju algorithm*/ int dfn[3005], t = 0, visited[3005], rank_g[3005]; int hash_tab[3005][3005]; void get_dfn(int i) { if (!visited[i]) { visited[i] = 1; for (int k = basic.head[i]; k; k = basic.edge[k].next) get_dfn(basic.edge[k].to); dfn[++t] = i; } } void dfs(int i, int group) { #ifdef DEBUG cout << "DEBUG DFS CALLED i = " << i << " ; group = " << group << endl; #endif visited[i] = group; rank_g[group] = min(rank_g[group], basic.rank[i]); for (int k = reversed.head[i]; k; k = reversed.edge[k].next) if (!visited[reversed.edge[k].to]) dfs(reversed.edge[k].to, group); } /*work functions*/ // using by function::able & funcion::work queue<int> que; bool killed[3005]; bool able() { int count = 0; for (int i = 1; i <= n; i++) if (basic.rank[i] <= 233333333) { que.push(i); killed[i] = 1; } while (!que.empty()) { int i = que.front(); que.pop(); count++; for (int k = basic.head[i]; k; k = basic.edge[k].next) { int to = basic.edge[k].to; if (!killed[to]) { killed[to] = 1; que.push(to); } } } return count == n; } void view(const graph &g) { cout << "VIEWING GRAPH......" << endl; int k; cin >> k; for (int i = 1; i <= n; i++) { if (g.head[i]) cout << "." << i << endl; for (int k = g.head[i]; k; k = g.edge[i].next) cout << "--\t" << g.edge[k].to << endl; } cout << "Finish." << endl; } void work() { #ifdef DEBUG view(basic); view(solved); #endif if (!able()) { cout << "NO" << endl; for (int i = 1; i <= n; i++) if (!killed[i]) { cout << i << endl; return; } } int ans = 0; for (int i = 1; i <= grp; i++) if (solved.rd[i] == 0) { #ifdef DEBUG cout << i << endl; #endif ans += rank_g[i]; } cout << "YES" << endl << ans << endl; } /*main function*/ int main() { memset(visited, 0, sizeof visited); memset(rank_g, 127/3, sizeof rank_g); ios::sync_with_stdio(false); cin >> n; cin >> p; for (int i = 1; i <= p; i++) { int a, b; cin >> a >> b; basic.edit_rank(a, b); } cin >> r; for (int i = 1; i <= r; i++) { int a, b; cin >> a >> b; basic.push(a, b); reversed.push(b, a); } /* main process for strong connected graph*/ for (int i = 1; i <= n; i++) get_dfn(i); memset(visited, 0, sizeof visited); for (int i = t; i; i--) if (!visited[dfn[i]]) dfs(dfn[i], ++grp); #ifdef DEBUG for (int i = 1; i <= n; i++) cout << visited[i] << " "; cout << endl; #endif memset(hash_tab, 0, sizeof hash_tab); for (int i = 1; i <= n; i++) for (int k = basic.head[i]; k; k = basic.edge[k].next) { int to = basic.edge[k].to; if (visited[to] != visited[i] && !hash_tab[visited[i]][visited[to]]) { solved.push(visited[i], visited[to]); hash_tab[visited[i]][visited[to]] = 1; } } /* main work */ work(); return 0; }
注:代码用vscode完成,果然优美2333.
相关文章推荐
- luogu解题报告:P1186玛丽卡【图论/最短路/堆优化dijkstra】
- luogu1262 间谍网络(tarjan缩点)
- luogu解题报告:P1119灾后重建【图论/最短路】
- 间谍网络--tarjan 解题报告
- P1262 间谍网络 (tarjan缩点 水过去)
- P1262 间谍网络 (tarjan缩点 水过去)
- Tarjan缩点【p1262】间谍网络
- 【POJ1182】食物链,思路+数据+代码,可能是史上关于这道题最详细的解题报告
- 第36届acm_icpc 北京赛区,网络赛解题报告 & 比赛log
- zsacm第一期网络练习解题报告
- 【POJ3009 - Curling】 解题报告+思路+代码+教训(看别人的报告过的)
- 【poj3320】Jessica's reading problem,解题报告+数据+代码
- 【HDU2780 - Su-Su-Sudoku】 解题报告+思路+代码,差点一次AC T^T
- tyvj 1153间谍网络 tarjan+缩点
- 【poj1164】The Castle,解题报告+思路+代码+数据
- 【POJ2488】 A knight's Journey 解题报告 测试数据+代码+思路
- 【Grids2418】Hardwood Species解题报告+代码
- 大连赛区网络赛部分题目解题报告
- 【poj3349】SnowFlake snow SnowFlake 解题报告+代码
- 【网络中心】解题报告