您的位置:首页 > 产品设计 > UI/UE

UVA11324 The Largest Clique

2013-05-29 23:35 288 查看
通往另一个世界的虫洞

tarjan缩点+dp求最长路

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
struct edge{
int u, v, next;
}e[55555];
const int N = 1111;
int pre
, lowlink
, sccno
, dfs_clock, scc_cnt, first
, tot;
int G

, n, m, w
, d
;
bool vis
;
stack<int> S;
void init(int x, int y){
e[tot].u = x; e[tot].v = y; e[tot].next = first[x]; first[x] = tot++;
}
void dfs(int u){
pre[u] = lowlink[u] = ++dfs_clock;
S.push(u);
for (int i = first[u]; i != -1; i = e[i].next){
int v = e[i].v;
if (!pre[v]){
dfs(v);
lowlink[u] = min(lowlink[u], lowlink[v]);
}
else if (!sccno[v])
lowlink[u] = min(lowlink[u], pre[v]);
}
if (lowlink[u] == pre[u]){
scc_cnt += 1;
for (;;){
int x = S.top(); S.pop();
sccno[x] = scc_cnt;
if (x == u) break;
}
}
}
void tarjan(int n){
dfs_clock = scc_cnt = 0;
memset(sccno, 0, sizeof(sccno));
memset(pre, 0, sizeof(pre));
for (int i = 1; i <= n; i++)
if (!pre[i]) dfs(i);
}
int dp(int i){
int &ans = d[i];
if (vis[i]) return ans;
vis[i] = 1; ans = w[i];
for (int j = 1; j <= scc_cnt; j++)
if (G[i][j]) ans = max(ans, dp(j) + w[i]);
return ans;
}
int main(){
int cs; scanf("%d", &cs);
while(cs--){
tot = 0; memset(first, -1, sizeof(first));
memset(e, 0, sizeof(e));
scanf("%d%d", &n, &m);
int x, y;
for (int i = 0; i < m; i++){
scanf("%d%d", &x, &y);
init(x, y);
}
tarjan(n);
memset(w, 0, sizeof(w));
memset(G, 0, sizeof(G));
for (int i = 1; i <= n; i++)
w[sccno[i]] += 1;
for (int u = 1; u <= n; u++)
for (int j = first[u]; j != -1; j = e[j].next){
int v = e[j].v;
if (sccno[u] != sccno[v]) G[sccno[u]][sccno[v]] = w[sccno[u]];
}
memset(d, 0, sizeof(d));
memset(vis, 0, sizeof(vis));
int ans = 0;
for (int i = 1; i <= scc_cnt; i++)
ans = max(ans, dp(i));
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: