蒟蒻求助,缩点+DAG拓扑 21pts WA,玄关

P3119 [USACO15JAN] Grass Cownoisseur G

@[liuenyin](/user/892979) 思路和[这篇题解](https://www.luogu.com.cn/blog/user21621/solution-p3119)有点像。
by liuenyin @ 2023-08-27 18:51:56


@[liuenyin](/user/892979) 新代码(改了几个地方,之前没O2全wa,现在开不开都是21pts ```cpp #include<bits/stdc++.h> using namespace std; #define int long long //#define debug typedef long long ll; const int N=1e5+5; const int M=1e5+5; /* 思路: Tarjan+topo */ vector<int> vec[N];//原图 //Tarjan配套 int scc_cnt; int sccno[N]; int dfs_clock; int dfn[N]; int low[N]; int scc_w[N]; stack<int> s; //缩点配套 vector<int> G1[N];//正图 vector<int> G2[N];//反图 //拓扑配套 queue<int> q1; queue<int> q2; int f1[N];//f1[i] 从1到i的最长路 int f2[N];//f2[i] i->1最长路 int in1[N];//正图入度 int in2[N];//反着的 int n,m; //tarjan void dfs(int u){ dfs_clock++; dfn[u]=low[u]=dfs_clock; s.push(u); for(int i=0;i<vec[u].size();i++){ int v=vec[u][i]; if(!dfn[v]){ dfs(v); low[u]=min(low[u],low[v]); } else if(!sccno[v]){ low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]){ //new scc scc_cnt++; int x=0,val=0; do{ x=s.top(); sccno[x]=scc_cnt; s.pop(); val++; }while(x!=u); scc_w[scc_cnt]=val; } } void find_scc(){ memset(sccno,0,sizeof sccno); memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); memset(scc_w,0,sizeof scc_w); dfs_clock=scc_cnt=0; for(int i=1;i<=n;i++){ if(!dfn[i]){ dfs(i); } } } //缩点 void sd(){ for(int i=1;i<=n;i++){ for(int j=0;j<vec[i].size();j++){ int v=vec[i][j]; if(sccno[i]==sccno[v])continue; G1[sccno[i]].push_back(sccno[v]); in1[sccno[v]]++; G2[sccno[v]].push_back(sccno[i]); in2[sccno[i]]++; } } } void bfs1(){ f1[1]=scc_w[sccno[1]]; for(int i=1;i<=scc_cnt;i++){ if(!in1[i]){ q1.push(i); } } while(!q1.empty()){ int tp=q1.front(); q1.pop(); for(int i=0;i<G1[tp].size();i++){ int v=G1[tp][i]; in1[v]--; if(f1[tp]>0)f1[v]=max(f1[v],f1[tp]+scc_w[v]); if(!in1[v]){ q1.push(v); } } } } void bfs2(){ f2[1]=scc_w[sccno[1]]; for(int i=1;i<=scc_cnt;i++){ if(!in2[i]){ q2.push(i); } } while(!q2.empty()){ int tp=q2.front(); q2.pop(); for(int i=0;i<G2[tp].size();i++){ int v=G2[tp][i]; in2[v]--; if(f2[tp]>0)f2[v]=max(f2[v],f2[tp]+scc_w[v]); if(!in2[v]){ q2.push(v); } } } } //求max int solve(){ int mx=scc_w[sccno[1]]; for(int i=1;i<=n;i++){ #ifdef debug cout<<sccno[i]<<" "<<scc_w[sccno[i]]<<" "<<f1[sccno[i]]<<" "<<f2[sccno[i]]<<endl; #endif for(int j=0;j<vec[i].size();j++){ if(sccno[i]!=sccno[vec[i][j]] and f1[sccno[vec[i][j]]]>0 and f2[sccno[i]]>0)mx=max(mx,f1[sccno[vec[i][j]]]+f2[sccno[i]]-scc_w[sccno[1]]); } } return mx; } signed main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; vec[x].push_back(y); } find_scc(); sd(); for(int i=1;i<=n+5;i++)f1[i]=f2[i]=-1e9; bfs1(); bfs2(); cout<<solve(); return 0; } ```
by liuenyin @ 2023-08-28 15:56:54


```cpp #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int sj=100010; int dfn[sj],low[sj],c[sj],jl[sj],dis[sj],s[sj]; int o[sj],h[sj],l[sj],w[sj]; int m,n,e1,e2,e3,cnt,ge,zh,ans; bool r[sj]; struct B { int v,ne; }b[sj]; struct BS { int u,to,nex; }bs[sj]; struct BSS { int to,nex; }bss[sj]; inline int re() { int jg=0,jk=0; jk=getchar()-'0'; if(jk>=0&&jk<=9) jg+=jk; jk=getchar()-'0'; while(jk>=0&&jk<=9) { jg*=10; jg+=jk; jk=getchar()-'0'; } return jg; } void add(int x,int y) { b[e1].v=y; b[e1].ne=h[x]; h[x]=e1++; } void ad2(int x,int y) { bs[e2].to=y; bs[e2].nex=l[x]; bs[e2].u=x; l[x]=e2++; } void ad3(int x,int y) { bss[e3].to=y; bss[e3].nex=o[x]; o[x]=e3++; } void init() { n=re(); m=re(); memset(h,-1,sizeof(h)); memset(l,-1,sizeof(l)); memset(o,-1,sizeof(o)); int a1,a2; for(int i=1;i<=m;i++) { a1=re(); a2=re(); add(a1,a2); } } int bj(int x,int y) { return x<y?x:y; } void spfa1(int x) { dis[x]=w[x]; r[x]=1; queue<int> q; q.push(x); int f; while(!q.empty()) { f=q.front(); for(int i=l[f];i!=-1;i=bs[i].nex) { if(dis[bs[i].to]<dis[f]+w[bs[i].to]) { dis[bs[i].to]=dis[f]+w[bs[i].to]; if(r[bs[i].to]!=1) { q.push(bs[i].to); r[bs[i].to]=1; } } } r[f]=0; q.pop(); } } void spfa2(int x) { dis[x]=w[x]; r[x]=1; queue<int> q; q.push(x); int f; while(!q.empty()) { f=q.front(); for(int i=o[f];i!=-1;i=bss[i].nex) if(dis[bss[i].to]<dis[f]+w[bss[i].to]) { dis[bss[i].to]=dis[f]+w[bss[i].to]; if(r[bss[i].to]!=1) { q.push(bss[i].to); r[bss[i].to]=1; } } r[f]=0; q.pop(); } } void tarjan(int x) { dfn[x]=low[x]=++cnt; s[++ge]=x; r[x]=1; for(int i=h[x];i!=-1;i=b[i].ne) { if(!dfn[b[i].v]) { tarjan(b[i].v); low[x]=bj(low[x],low[b[i].v]); } else if(r[b[i].v]) low[x]=bj(low[x],dfn[b[i].v]); } if(low[x]==dfn[x]) { int li; zh++; do { li=s[ge--]; c[li]=zh; w[zh]++; r[li]=0; }while(li!=x); } } int db(int &x,int y) { x=x>y?x:y; } int main() { init(); for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) for(int j=h[i];j!=-1;j=b[j].ne) if(c[i]!=c[b[j].v]) { ad2(c[i],c[b[j].v]); ad3(c[b[j].v],c[i]); } memset(r,0,sizeof(r)); memset(dis,0,sizeof(dis)); spfa1(c[1]); for(int i=1;i<=zh;i++) jl[i]=dis[i]; memset(r,0,sizeof(r)); memset(dis,0,sizeof(dis)); spfa2(c[1]); ans=1; for(int i=0;i<e2;i++) if(jl[bs[i].to]&&dis[bs[i].u]) db(ans,jl[bs[i].to]+dis[bs[i].u]-w[c[1]]); printf("%d",ans); return 0; } ```
by chaizechen_czc @ 2023-08-31 19:29:41


@[liuenyin](/user/892979)
by chaizechen_czc @ 2023-08-31 19:30:11


@[chaizechen_czc](/user/877062) 感谢
by liuenyin @ 2023-09-05 18:49:05


@[chaizechen_czc](/user/877062) 不过您能看出来我代码中的问题吗?(已关
by liuenyin @ 2023-09-05 18:49:42


@[liuenyin](/user/892979) ok 没事了
by liuenyin @ 2023-09-05 19:37:43


经测试,是bfs初始条件炸了(感谢题解对拍 hack: ``` 6 13 4 6 1 5 4 1 5 2 2 4 5 3 6 2 5 4 4 6 4 3 1 3 1 4 1 2 ``` std out: `6` my out: `10`
by liuenyin @ 2023-09-05 19:39:12


没事
by chaizechen_czc @ 2023-09-06 20:42:05


|