码迷,mamicode.com
首页 > 其他好文 > 详细

UVAlive11324 The Largest Clique(scc+dp)

时间:2015-12-17 19:11:05      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

 

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=30726

 

【思路】

       强连通分量+动归。

       求scc后缩点,以scc中的节点数作为权值,则问题转化为求一个DAG上的最大权路径,可以用dp求解。

 

【代码】

 

 1 #include<cstdio>
 2 #include<stack>
 3 #include<vector>
 4 #include<cstring>
 5 #include<iostream>
 6 using namespace std;
 7 
 8 const int maxn = 1000+10;
 9 const int maxm = 2000000+10;
10 
11 int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
12 vector<int> G[maxn];
13 stack<int> S;
14 
15 int dfs(int u) {
16     pre[u]=lowlink[u]=++dfs_clock;
17     S.push(u);
18     for(int i=0;i<G[u].size();i++) {
19         int v=G[u][i];
20         if(!pre[v]) {
21             dfs(v);
22             lowlink[u]=min(lowlink[u],lowlink[v]);
23         }
24         else if(!sccno[v]) {
25             lowlink[u]=min(lowlink[u],pre[v]);
26         }
27     }
28     if(lowlink[u]==pre[u]) {
29         scc_cnt++;
30         for(;;) {
31             int x=S.top(); S.pop();
32             sccno[x]=scc_cnt;
33             if(x==u) break;
34         }
35     }
36 }
37 void find_scc(int n) {
38     memset(pre,0,sizeof(pre));
39     memset(sccno,0,sizeof(sccno));
40     scc_cnt=dfs_clock=0;
41     for(int i=0;i<n;i++)  
42     if(!pre[i]) dfs(i);
43 }
44 
45 int T,n,m;
46 int val[maxn];
47 struct Edge{  int u,v,next; } e[maxm];
48 int en,front[maxm];
49 void AddEdge(int u,int v) {
50     en++; e[en].u=u,e[en].v=v; e[en].next=front[u],front[u]=en;
51 }
52 
53 int d[maxn];
54 int dp(int u) {
55     int& ans=d[u];
56     if(ans) return ans;
57     ans=0;
58     for(int i=front[u];i>=0;i=e[i].next) {
59         int v=e[i].v;
60         ans=max(ans,dp(v));
61      }
62     ans+=val[u];
63     return ans;
64 }
65 void init() {
66     en=-1;
67     memset(front,-1,sizeof(front));
68     memset(val,0,sizeof(val));
69     memset(d,0,sizeof(d));
70     for(int i=0;i<=n;i++) G[i].clear();
71 }
72 int main() {
73     scanf("%d",&T);
74     while(T--) {
75         scanf("%d%d",&n,&m);
76         init();
77         int u,v;
78         for(int i=0;i<m;i++) {
79             scanf("%d%d",&u,&v);
80             u--,v--;
81             G[u].push_back(v);
82         }
83         find_scc(n);
84         for(int i=0;i<n;i++) {
85             val[sccno[i]]++;
86             for(int j=0;j<G[i].size();j++) {
87                 int v=G[i][j];
88                 if(sccno[i]!=sccno[v]) AddEdge(sccno[i],sccno[v]);
89             }
90         }
91         int ans=0;
92         for(int i=1;i<=scc_cnt;i++)  ans=max(ans,dp(i));
93         printf("%d\n",ans);
94     }
95     return 0;
96 }

 

ps:实测该题vector数组式存边较自写邻接表快

 

UVAlive11324 The Largest Clique(scc+dp)

标签:

原文地址:http://www.cnblogs.com/lidaxin/p/5054840.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!