题目链接


Solution

大概是个裸题.

可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路.

于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了.

同时由于是拓扑序DP,要去掉所有的重边.

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100008;
struct sj{int to,next;}a[maxn*10];
ll mod,dfn[maxn],low[maxn];
ll head[maxn],belong[maxn];
ll du[maxn],w[maxn],v[maxn];
ll tot,sta[maxn],top,size,cnt;
ll num,n,m;
ll f[maxn],js[maxn],ans,ans_siz;
struct kk{int to,fr;}cc[maxn*10]; ll read()
{
char ch=getchar(); ll f=1,w=0;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();}
return f*w;
} void add(int x,int y)
{
a[++size].to=y;
a[size].next=head[x];
head[x]=size;
} void tarjan(int x)
{
dfn[x]=low[x]=++tot;
sta[++top]=x;
v[x]=1;
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(!dfn[tt]){
tarjan(tt);
low[x]=min(low[x],low[tt]);
}
else if(v[tt]) low[x]=min(low[x],dfn[tt]);
}
if(dfn[x]==low[x])
{
belong[x]=++cnt;
v[x]=0;
do{
w[cnt]++;
belong[sta[top]]=cnt;
v[sta[top]]=0;
}while(sta[top--]!=x);
}
} bool cmp(kk x,kk y)
{
if(x.fr==y.fr)return x.to<y.to;
else return x.fr<y.fr;
} void work()
{
queue<int>q;
for(int i=1;i<=cnt;i++)
if(!du[i])
q.push(i),v[i]=1,f[i]=w[i],js[i]=1;
while(!q.empty())
{
int x=q.front(); q.pop();
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
du[tt]--;
if(!du[tt]&&!v[tt])q.push(tt),v[tt]=1;
if(f[tt]==w[tt]+f[x])
js[tt]+=js[x],js[tt]%=mod;
if(f[tt]<w[tt]+f[x])
{
f[tt]=w[tt]+f[x];
js[tt]=js[x]%mod;
}
}
}
} int main()
{
n=read(); m=read(); mod=read();
for(int i=1;i<=m;i++)
add(read(),read());
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int x=1;x<=n;x++)
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(belong[tt]!=belong[x])
cc[++num].fr=belong[x],cc[num].to=belong[tt];
}
memset(a,0,sizeof(a));
memset(head,0,sizeof(head));
size=0; sort(cc+1,cc+num+1,cmp); for(int i=1;i<=num;i++)
{
if(cc[i].fr==cc[i-1].fr&&cc[i].to==cc[i-1].to)continue;
add(cc[i].fr,cc[i].to),du[cc[i].to]++;
}
work();
for(int i=1;i<=cnt;i++)
if(f[i]>ans)
ans=f[i],ans_siz=js[i];
else if(f[i]==ans)
ans_siz+=js[i],ans_siz%=mod;
cout<<ans<<endl<<(ans_siz+mod)%mod<<endl;
return 0;
}

最新文章

  1. js callee,caller学习
  2. iOS开发系列--Objective-C之类和对象
  3. SqlServer自动化分区
  4. ABAP 内表的行列转换
  5. Asp.Net customErrors与httpErrors的区别
  6. Apache+PHP+Mysql 集成环境 几个软件pk
  7. vijos 1038 括号+路径 ***
  8. xe mysql
  9. 《LDAP服务器的配置与客户端的测试》RHEL6——第一篇 运维工程师必考
  10. 马上学Android开发在线视频教程全集
  11. 教程-Delphi资源文件(全面分析于使用)
  12. POJ1201-Intervals(差动限制)
  13. U盘安装Mac OS X要点
  14. 服务器、IP地址和域名之间有什么关系?
  15. css文字上下居中,一行文字居中,两行或多行文字同样居中
  16. 并查集和树的一些性质 hdu1325
  17. 互联网IP地址的分配
  18. 微信小程序——&lt;radio&gt;&lt;/radio&gt;大小改变
  19. php中经常使用的string函数
  20. JS 控制页面超时后自动跳转到登陆页面

热门文章

  1. java sql database相关收集
  2. lca(最近公共祖先(离线))
  3. linux程序安装及包管理
  4. PAT (Basic Level) Practise (中文)- 1010. 一元多项式求导 (25)
  5. 【转】VxWorks信号量分析
  6. Codevs1080 线段树练习
  7. 在Keras中导入测试数据的方法
  8. VIM 编辑器 -使用详解记录
  9. Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery)
  10. Maven配置项目依赖使用本地仓库的方法汇总