ZOJ-3630-Information 解题报告
2014-12-26 14:51
302 查看
强连通分量题,看错好几次还以为是双连通分量求割点之类的题。题意:A国和B国打仗,B国有n个城市,每一个城市都有一个***和发射器用来传递消息。有些城市可能未发送任何消息,有些城市可能未接收任何消息。现在把那些可以互相直接或间接发送和接收消息的城市编成一个组,一个组中的任意两个成员都能互相直接或间接地发送和接收消息。每一个城市都最多只能属于一个组,并且每一个组的城市都至少是两个以上,否则不算一个组。现在A国想要摧毁B国的一个城市,使得摧毁之后B国城市数最多的那个组城市数最少并输出这个组的城市数。
我的解题思路:初看好几遍还以为求割点割完之后成员最多的双连通分量。其实,这是一个有向图。Orz,求的是强连通分量权。这里用的方法其实很暴力,枚举每一个点作为摧毁点求最大强连通分量权,然后算出这些最大强连通分量权的最小值。
我的解题代码:强连通分量Tarjan算法,不用缩点了
我的解题思路:初看好几遍还以为求割点割完之后成员最多的双连通分量。其实,这是一个有向图。Orz,求的是强连通分量权。这里用的方法其实很暴力,枚举每一个点作为摧毁点求最大强连通分量权,然后算出这些最大强连通分量权的最小值。
我的解题代码:强连通分量Tarjan算法,不用缩点了
#include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #include <vector> #include <queue> using namespace std; const int N = 10001; const int INF = 0x3f3f3f3f; vector<int> e ; int dfn , low ; int stack , stop; bool instack ; int timer, sccn; int n, m; int tempans, ans; //中间答案和最终答案 void InitRead(); void DataProcess(); void Tarjan(int x, int z); //z是枚举的摧毁掉的点 int main() { while (~scanf("%d %d", &n, &m)) { InitRead(); DataProcess(); } return 0; } void InitRead() { timer = tempans = stop = sccn = 0; ans = INF; //最终答案求最小值因此赋值为无穷大INF memset(dfn, 0, sizeof(dfn)); memset(instack, false, sizeof(instack)); for (int i=0; i<n; ++i) { e[i].clear(); } int a, b; for (int i=0; i<m; ++i) { scanf("%d %d", &a, &b); e[a].push_back(b); } return; } void DataProcess() { for (int i=0; i<n; ++i) { memset(dfn, 0, sizeof(dfn)); tempans = 0; //中间答案求最大值因此赋值为0 for (int j=0; j<n; ++j) { if (!dfn[j] && j != i) Tarjan(j, i); } ans = min(ans, tempans); } printf("%d\n", ans > 1 ? ans : 0); //如果无法成员数构成一个组则输出0 return; } void Tarjan(int x, int z) { dfn[x] = low[x] = ++timer; stack[stop++] = x; instack[x] = true; int size = e[x].size(); int y; for (int i=0; i<size; ++i) { y = e[x][i]; if (y == z) continue; //已摧毁的点忽略掉 if (!dfn[y]) { Tarjan(y, z); low[x] = min(low[x], low[y]); } else if (instack[y]) { low[x] = min(low[x], dfn[y]); } } if (dfn[x] == low[x]) { sccn++; int temp = 0; do { y = stack[--stop]; instack[y] = false; temp++; } while (x != y); tempans = max(tempans, temp); } return; }
相关文章推荐
- ZOJ 3878--解题报告
- ZOJ 3431 Escape! 解题报告
- [解题报告]ZOJ 1001
- ZOJ 3721 Final Exam Arrangement 解题报告 (贪心)
- ZOJ_1295解题报告
- ZOJ 2112 分块 解题报告
- zoj1005解题报告---菜鸟的第一篇解题报告
- ZOJ 3721 Final Exam Arrangement 解题报告
- POJ 3630 Phone List(解题报告)
- 【解题报告】 ZOJ 3640 Help Me Escape - 期望dp
- ZOJ 3772 Calculate the Function 解题报告
- [dp问题] Poj 1014 & Zoj 1149 (Dividing) 解题报告(转)
- ZOJ 3872--解题报告
- ZOJ 1635 - Directory Listing 解题报告
- ZOJ 3430 Detect the Virus 解题报告
- ZOJ 3256 Tour in the Castle 解题报告(插头DP)
- ZOJ 3714 Java Beans 解题报告
- ZOJ 1648 Circuit Board计算几何(解题报告)
- ZOJ 3716 Ribbon Gymnastics 解题报告
- 【解题报告】 ZOJ 3641 Information Sharing - 并查集+模拟