题目链接: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 ",ans); 94 } 95 return 0; 96 }
ps:实测该题vector数组式存边较自写邻接表快