P2272 [ZJOI2007]最大半连通子图
哎,这道题打了半个小时,调了两个小时,最后发现竟然是把
题意
定义最大半连通图:对于图中任意两点
看到题目时应该很容易想到,如果两点互相可以到达,那么它们必是半连通图,所以考虑先
设
最后答案就是
一些小建议
#include<bits/stdc++.h> #define N 1000005 #define M 10000005 using namespace std; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } int n,m,mod,tot,t,cnt,dis[N],maxn,ss,top; int dfn[N],low[N],s[N],vis[N],gp[N]; int Head[N],to[M],Next[M],val[N],S[N],pre[N]; map<pair<int,int>,bool> H; void add(int u,int v){to[++tot]=v,pre[tot]=u,Next[tot]=Head[u],Head[u]=tot;} void tarjan(int x){ dfn[x]=low[x]=++t,vis[x]=1,s[++top]=x; for(int i=Head[x];i;i=Next[i]){ int y=to[i]; if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]); else if(vis[y]) low[x]=min(low[x],dfn[y]); } if(dfn[x]==low[x]){ int k=s[top--];cnt++; while(x!=k){ gp[k]=cnt,val[cnt]++,vis[k]=0; k=s[top--]; } gp[x]=cnt,val[cnt]++,vis[x]=0,dis[cnt]=val[cnt],S[cnt]=1; } } int main(){ n=read(),m=read(),mod=read(); for(int i=1;i<=m;++i){ int u=read(),v=read();add(u,v); } for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i); m=tot; tot=0,memset(Head,0,sizeof(Head)); for(int i=1;i<=m;++i){ int x=gp[pre[i]],y=gp[to[i]]; if(x==y) continue; if(!H[make_pair(x,y)]) add(x,y),H[make_pair(x,y)]=1; } for(int x=cnt;x;--x){ for(int i=Head[x];i;i=Next[i]){ int y=to[i]; if(dis[y]<dis[x]+val[y]) dis[y]=dis[x]+val[y],S[y]=S[x]; else if(dis[y]==dis[x]+val[y]) S[y]=(S[y]+S[x])%mod; } } for(int i=1;i<=cnt;++i){ if(dis[i]>maxn) maxn=dis[i],ss=S[i]; else if(dis[i]==maxn) ss+=S[i],ss%=mod; } printf("%d\n%d\n",maxn,ss); return 0; }
本文作者:南风未起
本文链接:https://www.cnblogs.com/jiangchen4122/p/16841179.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步