题目链接 在其中纠错第一次wa代码
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #include <map> #include <algorithm> #include <set> using namespace std; typedef long long ll; typedef unsigned long long Ull; #define MM(a,b) memset(a,b,sizeof(a)); const double eps = 1e-10; const int inf =0x7f7f7f7f; const double pi=acos(-1); const int maxn=40000; vector<int> G[maxn+10],GG[maxn+10]; int n,m,vlue[maxn+10],pre[maxn+10],deg[maxn],dfs_clock,scc_cnt,sccno[maxn+10],lowlink[maxn+10]; stack<int> S; ll ori[maxn+10],dp[maxn+10]; ll maxx(ll a,ll b) { return a>b?a:b; } void tarjan(int u) { pre[u]=lowlink[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[u],lowlink[v]); } else if(!sccno[v]) lowlink[u]=min(lowlink[u],pre[v]); } if(lowlink[u]==pre[u]) { scc_cnt++; while(1) { int x=S.top();S.pop(); sccno[x]=scc_cnt; if(x==u) break; } } } void find_scc() { MM(pre,0); MM(sccno,0); scc_cnt=dfs_clock=0; for(int i=1;i<=n;i++) if(!pre[i]) tarjan(i); } set<int> st[maxn]; int main() { while(~scanf("%d %d",&n,&m)) { for(int i=1;i<=n;i++) { st[i].clear(); G[i].clear(); scanf("%d",&vlue[i]); } for(int i=1;i<=m;i++) { int u,v; scanf("%d %d",&u,&v); G[u].push_back(v); } find_scc(); for(int i=1;i<=scc_cnt;i++) { deg[i]=dp[i]=ori[i]=0; GG[i].clear(); } for(int i=1;i<=n;i++) ori[sccno[i]]+=vlue[i]; if(scc_cnt==1) {printf("%lld ",ori[1]);continue;}//需要特判,因为ans初始化为0或者 //不特判但将ans初始化为dp[1] for(int i=1;i<=n;i++) for(int j=0;j<G[i].size();j++) if(sccno[i]!=sccno[G[i][j]]) { int u=sccno[i],v=sccno[G[i][j]]; if(!st[u].count(v))//set判断图的连通性 { GG[u].push_back(v); st[u].insert(v); deg[v]++; } } ll ans=0; for(int i=1;i<=scc_cnt;i++) dp[i]=ori[i]; queue<int> q;//拓扑排序是需要借助BFS的 for(int i=1;i<=scc_cnt;i++) if(!deg[i]) q.push(i); while(q.size()) { int u=q.front();q.pop(); for(int i=0;i<GG[u].size();i++) { int v=GG[u][i]; dp[v]=maxx(dp[v],dp[u]+ori[v]); ans=maxx(ans,dp[v]); deg[v]--; if(!deg[v]) q.push(v); } } printf("%lld ",ans); } return 0; }
第一次wa代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #include <map> #include <algorithm> #include <set> using namespace std; typedef long long ll; typedef unsigned long long Ull; #define MM(a,b) memset(a,b,sizeof(a)); const double eps = 1e-10; const int inf =0x7f7f7f7f; const double pi=acos(-1); const int maxn=40000; vector<int> G[maxn+10],GG[maxn+10]; int n,m,vlue[maxn+10],ori[maxn+10],dp[maxn+10],pre[maxn+10],dfs_clock,scc_cnt,sccno[maxn+10],lowlink[maxn+10]; stack<int> S; void tarjan(int u) { pre[u]=lowlink[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[u],lowlink[v]); } else if(!sccno[v]) lowlink[u]=min(lowlink[u],pre[v]); } if(lowlink[u]==pre[u]) { scc_cnt++; while(1) { int x=S.top();S.pop(); sccno[x]=scc_cnt; if(x==u) break; } } } void find_scc() { MM(pre,0); MM(sccno,0); scc_cnt=dfs_clock=0; for(int i=1;i<=n;i++) if(!pre[i]) tarjan(i); } int main() { while(~scanf("%d %d",&n,&m)) { for(int i=1;i<=n;i++) { G[i].clear(); GG[i].clear(); scanf("%d",&vlue[i]); } for(int i=1;i<=m;i++) { int u,v; scanf("%d %d",&u,&v); G[u].push_back(v); } find_scc(); for(int i=1;i<=scc_cnt;i++) dp[i]=ori[i]=0; for(int i=1;i<=n;i++) ori[sccno[i]]+=vlue[i]; for(int i=1;i<=n;i++) for(int j=0;j<G[i].size();j++) if(sccno[i]!=sccno[G[i][j]]) { int u=sccno[i],v=sccno[G[i][j]]; if(lower_bound(GG[u].begin(),GG[u].end(),v)==GG[u].end()) GG[u].push_back(v); } int ans=0; for(int i=1;i<=scc_cnt;i++) dp[i]=ori[i]; for(int i=1;i<=scc_cnt;i++) for(int j=0;j<GG[i].size();j++) { int v=GG[i][j]; //printf("1::%d %d %d ",i,v,ori[i],ori[v]); dp[v]=max(dp[v],dp[i]+ori[v]); ans=max(ans,dp[v]); } printf("%d ",ans); } return 0; }