hdu 4635(强连通分量)
2013-08-25 13:40
337 查看
题目链接
不难得到如下结论:如果原图不是强连通, 那么最优解肯定是只剩两个强连通分量且每个分量内都为完全图, 可以列出数学表达式不难
发现最后的结果只和两个分量中的点数的乘积有关, 由于两者的和一定使两者的差尽可能大, 但一个点如果既有出度又有入度就不能单
独将它作为最后的一个点, 所以我要考虑只有出度或者入度的点。
不难得到如下结论:如果原图不是强连通, 那么最优解肯定是只剩两个强连通分量且每个分量内都为完全图, 可以列出数学表达式不难
发现最后的结果只和两个分量中的点数的乘积有关, 由于两者的和一定使两者的差尽可能大, 但一个点如果既有出度又有入度就不能单
独将它作为最后的一个点, 所以我要考虑只有出度或者入度的点。
#include <iostream> #include <stack> #include <queue> #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <vector> #include <cmath> using namespace std; typedef long long LL; const int N = 100005; const int M = N << 4; struct SCC { struct Edge { int v; Edge* next; void init(int a, Edge* e) { v = a, next = e; } }; Edge E[M], * head ; int low , pre , no ; int cnt ; int n, tot, sum, tdfn, m; int in , out ; stack<int> stk; void init(int n, int m) { this->n = n; this->m = m; for (int i = 0; i < n; i++) { head[i] = 0; no[i] = -1; pre[i] = 0; cnt[i] = 0; } tot = 0, sum = 0, tdfn = 0; } void add(int u, int v) { E[tot].init(v, head[u]); head[u] = &E[tot++]; } void dfs(int u) { pre[u] = low[u] = ++tdfn; stk.push(u); for (Edge* e = head[u]; e; e = e->next) { int v = e->v; if (!pre[v]) { dfs(v); low[u] = min(low[u], low[v]); } else if (no[v] == -1) low[u] = min(low[u], pre[v]); } if (low[u] == pre[u]) { sum++; while(1) { int x = stk.top(); stk.pop(); no[x] = sum - 1; if (x == u) break; } } } LL run() { for (int i = 0; i < n; i++) if (pre[i] == 0) dfs(i); if (sum == 1) return -1; int key = N; for (int i = 0; i < n; i++) { cnt[no[i]]++; } for (int i = 0; i < sum; i++) in[i] = 0, out[i] = 0; for (int i = 0; i < n; i++) for (Edge* e = head[i]; e; e = e->next) { int v = e->v; if (no[i] == no[v]) continue; in[no[v]]++; out[no[i]]++; } for (int i = 0; i < sum; i++) { if (in[i] && out[i]) continue; key = min(key, cnt[i]); } LL res = (LL) n * n - n - m - (LL)key * (n - key); return res; } }G; int main() { int test, u, v, n, m; scanf("%d", &test); int cas = 1; while (test--) { scanf("%d%d", &n, &m); G.init(n, m); for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); u--, v--; G.add(u, v); } cout << "Case " << cas++ << ": " << G.run() << endl; } return 0; }
相关文章推荐
- hdu 4635 Strongly connected 强连通分量
- HDU 4635 - Strongly connected(2013MUTC4-1004)(强连通分量)
- HDU 4635 Strongly connected 强连通分量
- HDU 4635 - Strongly connected(2013MUTC4-1004)(强连通分量)
- hdu 4635 Strongly connected 【图论-强连通分量-缩点-完全图】
- HDU 4635 Strongly connected ( 强连通分量 )
- HDU 4635 Strongly connected (有向图的强连通分量)
- HDU 4635 Strongly connected (2013多校4 1004 有向图的强连通分量)
- HDU-4635-Strongly connected(强连通分量)
- 多校第四场 Hdu 4635 强连通分量
- hdu 4635 Strongly connected (tarjan强连通分量)
- HDU 4635 Strongly connected(强连通分量,变形)
- HDU 4635 Strongly connected(强连通分量)
- HDU 4635 Strongly connected (强连通分量)
- HDU 4635 Strongly connected (强连通分量)
- hdu-4635-Strongly connected-强连通分量
- HDU 4635 Strongly connected(强连通分量)
- [HDOJ4635]Strongly connected(强连通分量,缩点)
- hdu 4635 Strongly connected【强连通Kosaraju+缩点染色+思维】
- hdu1269 迷宫城堡 强连通分量 tarjan算法(前向星实现)