[ZJOI2007]最大半连通子图
Posted lizehon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ZJOI2007]最大半连通子图相关的知识,希望对你有一定的参考价值。
图论基础
//经典图论题 二周目 2018.11.6
#include<bits/stdc++.h>
using namespace std;
inline int Max(int x,int y){return x>y?x:y;}
inline int Min(int x,int y){return x<y?x:y;}
typedef long long LL;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
}
const int MAXN=100005;
const int MAXM=1000005;
struct Edge{
int u,v,next;
}e[MAXM];
int first[MAXN],Ecnt;
inline void Add_edge(int u,int v){
e[++Ecnt]=(Edge){u,v,first[u]};
first[u]=Ecnt;
}
int low[MAXN],dfn[MAXN],ctg[MAXN],size[MAXN],st[MAXN],f[MAXN],g[MAXN],in[MAXN];
int n,m,mod,idx,ctgn,top,ans1,ans2;
typedef pair<int,int> pii;
set <pii> S;
queue <int> q;
inline void tarjan(int u){
low[u]=dfn[u]=++idx;
st[++top]=u;
for(int i=first[u];i;i=e[i].next){
int v=e[i].v;
if(!dfn[v]){
tarjan(v);
low[u]=Min(low[u],low[v]);
}
else if(!ctg[v]) low[u]=Min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
ctg[u]=++ctgn;
size[ctgn]++;
while(st[top]!=u){
ctg[st[top]]=ctgn;
size[ctgn]++;
top--;
}
top--;
}
}
int main(){
n=read(),m=read(),mod=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
Add_edge(x,y);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=1;i<=m;i++){
int u=e[i].u,v=e[i].v;
if(ctg[u]!=ctg[v])
S.insert(pii(ctg[u],ctg[v]));//用set判重
}
Ecnt=0;
memset(first,0,sizeof first);//重建图时清空first!!!!!
for(set<pii>::iterator it=S.begin();it!=S.end();it++){
Add_edge(it->first,it->second);
in[it->second]++;
}
for(int i=1;i<=ctgn;i++){
if(!in[i]){
q.push(i);
f[i]=size[i];//初始时放入长度
g[i]=1;
}
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=first[u];i;i=e[i].next){
int v=e[i].v;
if(--in[v]<=0) q.push(v);
if(f[u]+size[v]>f[v]){
f[v]=f[u]+size[v];
g[v]=0;
}
if(f[u]+size[v]==f[v])
(g[v]+=g[u])%=mod;
}
}
for(int i=1;i<=ctgn;i++){
if(f[i]>f[ans1])
ans1=i,ans2=0;
if(f[i]==f[ans1])
(ans2+=g[i])%=mod;
}
printf("%d\n%d\n",f[ans1],ans2);
}
以上是关于[ZJOI2007]最大半连通子图的主要内容,如果未能解决你的问题,请参考以下文章
tarjan 拓扑排序 dpbzoj1093: [ZJOI2007]最大半连通子图