UVA11324-- The Largest Clique(SCC+DP)
生活随笔
收集整理的這篇文章主要介紹了
UVA11324-- The Largest Clique(SCC+DP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
題意:給出一張有向圖,求一個結點數最大的結點集,使得該結點集中隨意兩個結點u和v滿足:要么u能夠到到v,要么v能夠到達u(u和v能夠互相到達)
思路:我們能夠縮點,用Tarjan求出全部強連通分量,讓每一個SCC的權值等于它的結點個數。因為SCC圖是有一個DAG,使用DP求解。
代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <stack> #include <algorithm>using namespace std;const int MAXN = 1005;vector<int> g[MAXN], scc[MAXN], G[MAXN]; stack<int> s; int pre[MAXN], lowlink[MAXN], sccno[MAXN], sccnum[MAXN], dfs_clock, scc_cnt; int d[MAXN]; int n, m;int Tarjan(int u) {lowlink[u] = pre[u] = ++dfs_clock;s.push(u);for (int i = 0; i < g[u].size(); i++) {int v = g[u][i]; if (!pre[v]) {Tarjan(v); lowlink[u] = min(lowlink[v], lowlink[u]);} else if (!sccno[v]) {lowlink[u] = min(lowlink[u], pre[v]); }}if (lowlink[u] == pre[u]) {scc_cnt++;for (;;) {int x = s.top(); s.pop();sccno[x] = scc_cnt;sccnum[sccno[x]]++;if (x == u) break;} } }void find_scc() {memset(pre, 0, sizeof(pre));memset(lowlink, 0, sizeof(lowlink));memset(sccno, 0, sizeof(sccno));memset(sccnum, 0, sizeof(sccnum));dfs_clock = scc_cnt = 0;for (int i = 0; i < n; i++)if (!pre[i])Tarjan(i); }int dp(int i) {int& ans = d[i]; if (ans > 0) return ans;ans = sccnum[i];for (int j = 0; j < G[i].size(); j++) {int v = G[i][j];ans = max(ans, dp(v) + sccnum[i]);}return ans; }int main() {int cas;scanf("%d", &cas);while (cas--) {scanf("%d%d", &n, &m);for (int i = 0; i < n; i++)g[i].clear();int u, v;for (int i = 0; i < m; i++) {scanf("%d%d", &u, &v); u--;v--;g[u].push_back(v);}find_scc();memset(d, -1, sizeof(d));memset(G, 0, sizeof(G));for (int u = 0; u < n; u++) {for (int i = 0; i < g[u].size(); i++) {int v = g[u][i]; if (sccno[u] != sccno[v]) G[sccno[u]].push_back(sccno[v]); } } int ans = 0;for (int i = 1; i <= scc_cnt; i++) ans = max(ans, dp(i));printf("%d\n", ans);}return 0; }總結
以上是生活随笔為你收集整理的UVA11324-- The Largest Clique(SCC+DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Horizon View 6-客户端连接
- 下一篇: 查看 SELinux状态及关闭SELin