rt,卡了一晚上了。我甚至是对着题解看了也没看出什么问题……
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct nd{
int from,to,nxt;
}li[300002],nli[300002];
int ind[100002],ptr,ind2[100002],ptr2;
bool torec[100002];
void add(int x,int y)
{
ptr++;
li[ptr]=((nd){x,y,ind[x]});
ind[x]=ptr;
}
void add2(int x,int y)
{
ptr2++;
nli[ptr2]=((nd){x,y,ind2[x]});
ind2[x]=ptr2;
}
int dfsx[100002],lowx[100002],cnt;
stack<int> s;
bool vis[100002];
int dcnt=0;
int sd[100002],sz[100002];
int in[100002];
void tarjan(int x)
{
// cout<<"tarjan"<<endl;
cnt++;
dfsx[x]=lowx[x]=cnt;
s.push(x);
vis[x]=true;
for(int i=ind[x];i!=-1;i=li[i].nxt)
{
if(dfsx[li[i].to]==0)
{
tarjan(li[i].to);
lowx[x]=min(lowx[x],lowx[li[i].to]);
}else{
if(vis[li[i].to])
{
lowx[x]=min(lowx[x],dfsx[li[i].to]);
}
}
}
if(dfsx[x]==lowx[x])
{
dcnt++;
while(s.size()&&s.top()!=x)
{
sd[s.top()]=dcnt;
vis[s.top()]=false;
sz[dcnt]++;
s.pop();
}
sd[s.top()]=dcnt;
vis[s.top()]=false;
sz[dcnt]++;
s.pop();
}
}
bool lstvis;
bool check(int pos)
{
// cout<<"checker"<<endl;
if(lstvis||sz[pos]>1)
{
return false;
}
for(int i=ind2[pos];i!=-1;i=nli[i].nxt)
{
if(in[nli[i].to]==1)
{
return false;
}
}
return lstvis=true;
}
int main()
{
cin>>n>>m;
int x,y;
ptr=0;
memset(ind,-1,sizeof(ind));
bool check1,check2;
for(int i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
add(x,y);
}
if(m==0)
{
printf("%.6lf",1.0/(1.0*n));
return 0;
}
if(n==1)
{
printf("%.6lf",1.0*0.0);
return 0;
}
cnt=0;
memset(dfsx,0,sizeof(dfsx));
memset(lowx,0,sizeof(lowx));
memset(vis,false,sizeof(vis));
memset(sd,0,sizeof(sd));
memset(sz,0,sizeof(sz));
for(int i=1;i<=n;i++)
{
if(dfsx[i]==0)
{
tarjan(i);
}
}
// for(int i=1;i<=n;i++)
// {
// cout<<sd[i]<<" "<<sz[i]<<endl;
// }
memset(ind2,-1,sizeof(ind2));
ptr2=0;
for(int i=1;i<=n;i++)
{
memset(torec,false,sizeof(torec));
for(int j=ind[i];j!=-1;j=li[j].nxt)
{
if(sd[i]!=sd[li[j].to]&&!torec[li[j].to])
{
add2(sd[i],sd[li[j].to]);
in[sd[li[j].to]]++;
torec[sd[li[j].to]]=true;
}
}
}
int ans=0;
lstvis=true;
for(int i=1;i<=dcnt;i++)
{
if(in[i]==0)
{
ans++;
}
if(in[i]>0||sz[i]>1)
{
continue;
}
if(lstvis)
{
bool jud=true;
for(int j=ind2[i];(j!=-1);j=nli[j].nxt)
{
if(in[nli[j].to]<=1)
{
jud=false;
break;
}
}
if(jud)
{
ans--;
lstvis=false;
}
}
}
printf("%.6lf\n",(double)(1.0*(n-ans)/n*1.0));
return 0;
}
/*
*/