# LG2272/BZOJ1093 「ZJOI2007」最大半连通子图 Tarjan缩点+DAG求最长链

LG2272

BZOJ1093

## $\mathrm{Code}$

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){
fh=-1;ch=getchar();
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}

const int maxn=100000+7;
const int maxm=1000000+7;
int n,m,mod;

int size[maxn];

}

}

int dfn[maxn],low[maxn],cnt,sta[maxn],ind,top;
bool ins[maxn];

int bel[maxn],rd[maxn],cd[maxn];

void tarjan(int x){//错误笔记：Tarjan没写instack
low[x]=dfn[x]=++ind;sta[++top]=x;ins[x]=1;
int y=to_old[i];
if(dfn[y]){ if(ins[y]) low[x]=min(low[x],dfn[y]);}
else{
tarjan(y);low[x]=min(low[x],low[y]);
}
}
if(dfn[x]==low[x]){
++cnt;
while(sta[top]!=x){
bel[sta[top]]=cnt,ins[sta[top]]=0,top--;size[cnt]++;
}
bel[sta[top]]=cnt,top--;size[cnt]++;ins[x]=0;
}
}

set < pair<int,int> > st;

int lft;

bool str[maxn];

void toposort(){
lft=n;
for(int i=1;i<=cnt;i++){
if(!rd[i]) que[++rear]=i,--lft,str[i]=1;
}
while(fro<=rear){
int x=que[fro];++fro;
int y=to_new[i];--rd[y];
if(!rd[y]) que[++rear]=y,--lft;
}
}
}

int cot,length;

bool vis[maxn];
int dep[maxn];
int sum[maxn];

void dfs(int x,int fa){
if(vis[x]) return;
vis[x]=1;
if(!cd[x]){
dep[x]=size[x];sum[x]=1;return;
}
int y=to_new[i];
if(y==fa) continue;
dfs(y,x);
if(dep[y]+size[x]>dep[x]) dep[x]=dep[y]+size[x],sum[x]=sum[y]%mod;
else if(dep[y]+size[x]==dep[x]) sum[x]=(sum[x]+sum[y])%mod;
}
}

void calc(){
for(int i=1;i<=cnt;i++){
if(dep[i]>length){
length=dep[i];cot=sum[i];
}
else if(dep[i]==length){
cot=(cot+sum[i])%mod;
}
}
}

void debug_rebuild(){
puts("function debug_rebuild");
printf("Node number : %d\n",cnt);
printf("Edge number : %d\n",tot_new);
for(int i=1;i<=tot_new;i++){
printf("Edge %d u:%d v:%d\n",i,u_new[i],to_new[i]);
}
puts("\nbelong:");
for(register int i=1;i<=n;i++){
printf("Node %d belong to %d\n",i,bel[i]);
}
}

int main(){
for(int xx,yy,i=1;i<=m;i++){
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=1;i<=tot_old;i++){
int x=bel[u_old[i]],y=bel[to_old[i]];
if(x==y) continue;
if(st.count(make_pair(x,y))==1) continue;
++rd[y];++cd[x];
}
//debug!
/*	puts("");
puts("********************************************************");
puts("");
debug_rebuild();
puts("");
puts("********************************************************");
puts("");*/
//end debug

toposort();
for(int i=1;i<=cnt;i++){
if(!vis[i]&&str[i]) dfs(i,0);
}
calc();
printf("%d\n%d\n",length,cot);
return 0;
}

posted @ 2019-09-09 23:46  liubainian  阅读(...)  评论(...编辑  收藏