题意中两个半子图不同是指有点不同
好奇怪的一句话啊
就是子图中包含的点不同,不管边怎样
然后就是tarjan dp
注意不要连重边
窝用的是map判重
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<iostream>
#define T 100100
using namespace std;
int sc()
{
int i=0; char c=getchar();
while(c>'9'||c<'0') c=getchar();
while(c>='0'&&c<='9') i=i*10+c-'0',c=getchar();
return i;
}
int Head[T],Nxt[T*10],Lst[T*10],mx[T],sum[T];
int dfn[T],low[T],size[T],bl[T],st[T],vis[T];
int head[T],nxt[10*T],lst[10*T];
int Tot,tot,n,m,K,top,cnt,scc;
map<pair<int,int>,int>mp;
void Insert(int x,int y)
{
Lst[++Tot]=y;
Nxt[Tot]=Head[x];
Head[x]=Tot;
}
void insert(int x,int y)
{
lst[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void tarjan(int x)
{
low[x]=dfn[x]=++cnt;
st[++top]=x;
vis[x]=1;
for(int i=head[x];i;i=nxt[i])
{
if(vis[lst[i]])low[x]=min(low[x],dfn[lst[i]]);
else if(!dfn[lst[i]])
{
tarjan(lst[i]);
low[x]=min(low[x],low[lst[i]]);
}
}
if(dfn[x]==low[x])
{
int k=0;scc++;
while(k!=x)
{
k=st[top--];
bl[k]=scc;
size[scc]++;
vis[k]=0;
}
}
}
void dfs(int x)
{
vis[x]=1;
for(int i=Head[x];i;i=Nxt[i])
{
if(!vis[Lst[i]]) dfs(Lst[i]);
if(mx[x]<mx[Lst[i]])
{
mx[x]=mx[Lst[i]];
sum[x]=sum[Lst[i]];
}
else if(mx[x]==mx[Lst[i]])
sum[x]=(sum[x]+sum[Lst[i]])%K;
}
if(mx[x]==0)sum[x]=1;
mx[x]+=size[x];
//cout << x <<" "<<mx[x]<<" "<<sum[x]<<endl;
}
int main()
{
n=sc(),m=sc(),K=sc();
for(int i=1;i<=m;i++)
{
int x=sc(),y=sc();
insert(x,y);
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=nxt[j])
if(bl[i]!=bl[lst[j]])
{
if(!mp[make_pair(bl[i],bl[lst[j]])])
Insert(bl[i],bl[lst[j]]),
mp[make_pair(bl[i],bl[lst[j]])]=1;
}
int MX=0,ans=0;
for(int i=1;i<=scc;i++)
{
if(!vis[i]) dfs(i);
if(mx[i]>MX)
{
MX=mx[i];
ans=sum[i];
}
else if(mx[i]==MX)
ans=(ans+sum[i])%K;
}
cout<<MX<<endl<<ans;
return 0;
}