#include #include #include #include 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 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]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; }