holiday/8.19/C-kill.cpp
2022-08-21 08:22:24 +08:00

157 lines
2.2 KiB
C++

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1e5+5,NN=3e5+5;
int n,e;
int to[NN],ne[NN];
int h[N];
int dfn[N],low[N];
bool b[N];
int s[N];//stack
int cnt;
int tot,top;
int id;
int nid[N];
int now;
bool no[N];
int fa[N];
vector<int> tfa[N];
void add(int u,int v)
{
to[++cnt]=v;
ne[cnt]=h[u];
h[u]=cnt;
}
void initialise(int n)
{
cnt=0;
tot=0;
top=0;
id=n;
memset(b,0,sizeof(bool)*(n+1));
memset(no,0,sizeof(bool)*(n+1));
memset(h,0,sizeof(int)*(n+1));
memset(dfn,0,sizeof(int)*(n+1));//WA 根据它判断有无经过
}
void tarjan(int u)
{
// printf("%d:",u);
int v;
dfn[u]=++tot;
low[u]=tot;
s[++top]=u;
b[u]=1;
for(int i=h[u]; i; i=ne[i])
{
v=to[i];
// printf("%d ",v);
if(!dfn[v])
{
tarjan(v);
low[u]=low[u]<low[v]? low[u]:low[v];
}
else if(b[v])
{
low[u]=low[u]<dfn[v]? low[u]:dfn[v];
}
}
if(low[u]==dfn[u])
{
id++;
// printf("(%d):",id);
do
{
// printf("%d ",s[top]);
nid[s[top]]=id;
b[s[top]]=0;
}
while(s[top--]!=u&&top>0);
// printf("\n");
}
}
void dfs(int u,int fat)
{
for(int i=h[u]; i; i=ne[i])
{
int v=to[i];
tfa[v].push_back(fat);
dfs(v,fat);//这句居然没写
}
}
int main()
{
int u,v;
// while(~scanf("%d",&n)&&n)
// {
scanf("%d",&n);
initialise(n);
scanf("%d",&e);
for(int i=1; i<=e; i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
//一开始放在前面,忽略了没有边的情况
for(int i=1; i<=n; i++)
{
// add(0,i);
if(!dfn[i])
{
tarjan(i);
}
}
// tarjan(0);
int l=cnt+1;
for(int i=1; i<=n; i++)
{
for(int j=h[i]; j; j=ne[j])
{
v=to[j];
if(nid[v]!=nid[i])
{
add(nid[i],nid[v]);
fa[nid[v]]++;
// printf("(%d)to(%d)%d\n",nid[i],nid[v],fa[nid[v]]);
}
}
}
int ans=0;
for(int i=n+1; i<=id; i++)
{
// printf("(%d)",i);
if(fa[i]==0 )
{
ans++;
dfs(i,i);
}
}
// printf("%d ",ans);
bool des=0;
for(int i=n+1; i<=id; i++)
{
if(fa[i]==0 )
{
int j=h[i];//i ->u
for(; j; j=ne[j])
{
v=to[j];
// printf("%d to %d:%d\n",i,v,tfa[v].size());
if(tfa[v].size()==1)
{
break;
}
}
if(!j)
{
des=1;
break;
}
}
}
printf("%.6lf",1.0-(ans-des)*1.0/n);
// }
return 0;
}