社区讨论
小可爱求助qwq
P2272[ZJOI2007] 最大半连通子图参与者 10已保存回复 17
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 17 条
- 当前快照
- 1 份
- 快照标识符
- @mi6vakvh
- 此快照首次捕获于
- 2025/11/20 11:24 4 个月前
- 此快照最后确认于
- 2025/11/20 14:45 4 个月前
一脸懵逼
要是帮忙解决的话,就把小可爱抱走吧
CPP// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,x;
int ans;int sum;int scc;
int u,v;
struct data{
int v;int next;
}edge[1000010],node[1000100];
int alist[100010];
int head[1000010];
int cnt;
void add(int u,int v)
{
edge[++cnt].v=v;
edge[cnt].next=alist[u];
alist[u]=cnt;
return ;
}
int d[1000010];
void ins(int u,int v)
{
node[++cnt].v=v;
node[cnt].next=head[u];
head[u]=cnt;
d[v]++;
return ;
}
int dfn[1000010];int dfu;
int stack[1000010];int top;
int low[10000010];bool book[1000010];
int poi[1000010];int bel[10000010];
void tarjan(int x)
{
low[x]=dfn[x]=++dfu;
stack[++top]=x;
book[x]=true;
int next=alist[x];
while(next)
{
// printf("%d %d\n",x,next);
int v=edge[next].v;
if(!dfn[v]) tarjan(v),low[x]=min(low[x],low[v]);
else if(book[v]) low[x]=min(low[x],dfn[v]);
next=edge[next].next;
}
int now=0;
if(low[x]==dfn[x])
{
scc++;
while(now!=x)
{
now=stack[top],top--;
book[now]=false;
poi[scc]++;
bel[now]=scc;
}
}
return ;
}
void rebuilt()
{
cnt=0;
for(int i=1;i<=n;i++){
int next=alist[i];
while(next)
{
if(bel[i]!=bel[edge[next].v])
ins(bel[i],bel[edge[next].v]);
// printf("%d %d\n",bel[i],bel[edge[next].v]);
next=edge[next].next;
}
}
return ;
}
queue<int> q;
int f[100010];int g[100010];int dp[100010];
void dynamic()
{
for(int i=1;i<=scc;i++){
if(!d[i]) q.push(i);
f[i]=poi[i],g[i]=1;
}
while(!q.empty())
{
int x=q.front();
q.pop();int next=head[x];
while(next)
{
d[node[next].v]--;
if(!d[node[next].v]) q.push(node[next].v);
if(dp[node[next].v==x])continue;
if(f[x]+poi[node[next].v]>f[node[next].v]){
f[node[next].v]=f[x]+poi[node[next].v];
g[node[next].v]=g[x];
}
else if(f[x]+poi[node[next].v]==f[node[next].v])
g[node[next].v]=(g[node[next].v]+g[x])%x;
dp[node[next].v]=x;
next=node[next].next;
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&x);
for(int i=1;i<=m;i++) scanf("%d%d",&u,&v),add(u,v);
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
rebuilt();dynamic();
for(int i=1;i<=scc;i++)
if(f[i]>ans) ans=f[i],sum=g[i];
else if(f[i]==ans) sum=(sum+g[i])%x;
// for(int i=1;i<=cnt;i++) printf("%d %d\n",node[i].v,node[i].next);
printf("%d\n%d",ans,sum%x);
return 0;
}
回复
共 17 条回复,欢迎继续交流。
正在加载回复...