- [ZJOI2007] 最大半连通子图
对拍
- 2025-7-3 20:57:25 @
第一行:两个整数,表示缩点后的节点数和边数.
接下来,每行两个整数,表示两点有一条边.
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=500001;
vector<int>edge[MAXN];
int instk[MAXN],dfn[MAXN],low[MAXN],belong[MAXN],tot,stknum,ans,n,m;
vector<int>scc[MAXN];
stack<int>stk;
//edge: 原来节点的边
//instk,dfn,low,belong,tot,stknum(scc数量): tarjan模板
//ans: 最大半连通子图大小
//n,m: 点数和边数
vector<int>g[MAXN];
int f[MAXN];
//g: 缩点以后的图
//f[i]: 缩点以后,以i节点开始 可以组成的 节点最多 的链的大小
set<pair<int,int>>st;
//st: 用于判重边
int mem[MAXN],s;
//mem: dfs记忆化用的
void tarjan(int x){
dfn[x]=low[x]=++tot,instk[x]=1;
stk.push(x);
for(int i:edge[x]){
if(!dfn[i]){
tarjan(i);
low[x]=min(low[x],low[i]);
}
else if(instk[i]){
low[x]=min(low[x],dfn[i]);
}
}
if(dfn[x]==low[x]){
int y;
stknum++;
do{
y=stk.top();
stk.pop();
scc[stknum].emplace_back(y);
instk[y]=0;
belong[y]=stknum;
}while(y!=x);
/*---模板分界线---*/
for(int a:scc[stknum]){
for(int z:edge[a]){
if(belong[a]!=belong[z])g[stknum].emplace_back(belong[z]);//建新图
}
}
for(int i:g[stknum]){
f[stknum]=max(f[stknum],f[i]);//找出 链大小最大 的儿子
}
f[stknum]+=scc[stknum].size();//加上自己的大小
ans=max(ans,f[stknum]);
}
}
int dfs(int u){
if(mem[u])return mem[u];
int sum=0;
for(int v:g[u]){
if(f[u]==f[v]+(int)scc[u].size())sum+=dfs(v);//只有大小符合需求的点才可以加上
sum%=s;//注意取模
}
if(!sum)sum=1;//叶子节点只有1种情况
mem[u]=sum%s;
return sum%s;
}
signed main(){
cin>>n>>m>>s;
if(n>m+1){
cout<<0;
return 0;
}
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
edge[u].emplace_back(v);
}
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i);
}
/*---模板分界线---*/
for(int i=1;i<=stknum;i++){//判重边:记录所有边
for(int j:g[i])st.insert({i,j});
g[i].clear();
}
for(auto i=st.begin();i!=st.end();i++){//判重边:把边放回去
g[i->first].emplace_back(i->second);
}
int sum=0;
for(int i=1;i<=stknum;i++){
if(f[i]==ans){//从 最大链的开始 的节点开始计算
sum+=dfs(i);
sum%=s;
}
}
int sumf=0;
for(int i=1;i<=stknum;i++)sumf+=g[i].size();
cout<<stknum<<" "<<sumf<<endl;
for(int i=1;i<=stknum;i++){
for(int j:g[i])cout<<i<<" "<<j<<endl;
}
// cout<<ans<<endl<<sum%s<<endl;//注意取模
}
0 comments
No comments so far...
Information
- ID
- 421
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 8
- Tags
- # Submissions
- 61
- Accepted
- 8
- Uploaded By