注意,加入环后,要考虑分母为0的情况
这样公然抄别人代码真的好吗?我的代码能力好弱呀!!!
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define maxn 100010 using namespace std; bool cir[maxn]; int vis[maxn]; int head[maxn],to[2*maxn],fa[maxn],next[2*maxn]; double len[2*maxn],d[maxn],f[maxn],gg[maxn],g[maxn]; int du[maxn]; int n,m,num,root,Time; void addedge(int x,int y,int z) { num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num; } void dfs1(int x) { vis[x]=1; for (int p=head[x];p;p=next[p]) if (!vis[to[p]] && !cir[to[p]]) { dfs1(to[p]); du[x]++; d[x]+=f[to[p]]+len[p]; } if (du[x]) f[x]=d[x]/(double)du[x]; if (x!=root) du[x]++; } void dfs2(int x) { vis[x]=1; for (int p=head[x];p;p=next[p]) if (!vis[to[p]] && !cir[to[p]]) { d[to[p]]+=(d[x]-f[to[p]]-len[p])/max(1,du[x]-1)+len[p]; dfs2(to[p]); } } void find(int x) { vis[x]=++Time; for (int p=head[x];p;p=next[p]) if (to[p]!=fa[x]) { if (!vis[to[p]]) fa[to[p]]=x,find(to[p]); else if (vis[to[p]]<vis[x]) { for(int y=x;y!=to[p];y=fa[y]) cir[y]=1; cir[to[p]]=1; } } } void solve_circle(int x,int fa) { bool flag=0; g[x]=0; for (int p=head[x];p;p=next[p]) if (to[p]!=root && to[p]!=fa && cir[to[p]]) { flag=1; solve_circle(to[p],x); g[x]+=g[to[p]]+len[p]; } if (x==root) return; int k=du[x];if (!k) k++; if (!flag) g[x]=d[x]/(double)k; else k=du[x]+1,g[x]=(g[x]+d[x])/(double)k; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); addedge(x,y,z);addedge(y,x,z); } if (m==n-1) { root=1; dfs1(1); memset(vis,0,sizeof(vis)); dfs2(1); } else { find(1); memset(vis,0,sizeof(vis)); for (int i=1;i<=n;i++) if (cir[i]) root=i,dfs1(i); for (int i=1;i<=n;i++) if (cir[i]) root=i,solve_circle(i,0),gg[i]=g[i]; memset(vis,0,sizeof(vis)); for (int i=1;i<=n;i++) if (cir[i]) du[i]+=2,d[i]+=gg[i]; for (int i=1;i<=n;i++) if (cir[i]) root=i,dfs2(i); } double ans=0; for (int i=1;i<=n;i++) ans+=d[i]/(double)du[i]; printf("%.5lf\n",ans/(double)n); return 0; }