crh1272336175
2020-07-18 08:16:08
① 若
② 若
那么我们可以从
与情况 11 对称,此时答案为
综上所述,
AC代码:
#include<bits/stdc++.h>
#pragma GCC opitimize(2)
using namespace std;
const int N=1e5+5;
namespace Read
{
inline int read()
{
int s=0,f=1; char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) s=s*10+(ch^48),ch=getchar();
return s*f;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
}using namespace Read;
namespace Gragh
{
int n,m,tot=0;
int head[N],Next[N<<1],des[N<<1];
inline void add(int a,int b)
{
Next[++tot]=head[a]; des[tot]=b;
head[a]=tot;
}
}using namespace Gragh;
namespace Tarjan
{
int num=0,cnt=0;
int low[N],dfn[N],ins[N],c[N];
stack<int> stk;
vector<int> scc[N];
void tarjan(int x)
{
low[x]=dfn[x]=++num;
stk.push(x); ins[x]=1;
for(int i=head[x]; i; i=Next[i])
{
int y=des[i];
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(ins[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x])
{
int y; cnt++;
do
{
y=stk.top(); stk.pop(); ins[y]=0;
c[y]=cnt; scc[cnt].push_back(y);
}while(y!=x);
}
}
}using namespace Tarjan;
namespace ContractionPoint
{
int tot2=0;
int head2[N],Next2[N<<1],des2[N<<1],in[N],out[N];
inline void add2(int a,int b)
{
Next2[++tot2]=head2[a]; des2[tot2]=b;
head2[a]=tot2; in[b]++; out[a]++;
}
}using namespace ContractionPoint;
int main()
{
n=read();
for(int i=1; i<=n; i++)
{
while(true)
{
int x=read();
if(!x) break;
add(i,x);
}
}
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=Next[i])
{
int y=des[i];
if(c[x]!=c[y]) add2(c[x],c[y]);
}
int ans1=0,ans2=0;
for(int i=1; i<=cnt; i++)
if(in[i]==0) ans1++;
for(int i=1; i<=cnt; i++)
if(out[i]==0) ans2++;
ans2=max(ans2,ans1);
if(cnt==1) ans2=0;
write(ans1),puts(""),write(ans2);
return 0;
}
注:本题解非原创,转载自https://www.acwing.com/solution/content/4663/