1. 程式人生 > >狂飆突進的幻想鄉

狂飆突進的幻想鄉

題目大意:給一張無向圖,每條邊有個(x,y),每條邊的邊權是ax+(1a)y。若a在[0,1]均勻隨機,問期望最短路是多少。n<=200,m<=400。x,y<=10^7且隨機生成。 題解:你可以直接辛普森積分水過。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<climits>
#include<cstdlib>
#include<ctime>
#include<queue> #include<vector> #include<utility> #define gc getchar() #define lint long long #define db long double #define pb push_back #define mp make_pair #define fir first #define sec second #define rep(i,a,b) for(int i=a;i<=b;i++) #define Rep(i,v) rep(i,0,(int)v.size()-1)
#define INF 2.0*INT_MAX #define N 210 #define M 410 #define debug(x) cerr<<#x<<"="<<x #define sp <<" " #define ln <<endl using namespace std; inline int inn() { int x,ch;while((ch=gc)<'0'||ch>'9'); x=ch^'0';while((ch=gc)>='0'&&ch<='9') x=(x<<1
)+(x<<3)+(ch^'0');return x; } const db eps=0.00000001;inline db gabs(db x) { return x<0?-x:x; } priority_queue<pair<db,int> > q;db d[N],w[M];bool vis[N]; vector<pair<int,db> > g[N];int u[M],v[M],x[M],y[M],n,m,s,t; inline db dijkstra(db a) { rep(i,1,n) d[i]=INF,vis[i]=0; while(!q.empty()) q.pop();q.push(mp(d[s]=0,s)); rep(i,1,n) g[i].clear();rep(i,1,m) w[i]=a*x[i]+(1-a)*y[i]; rep(i,1,m) g[u[i]].pb(mp(v[i],w[i])),g[v[i]].pb(mp(u[i],w[i])); while(!q.empty()) { int x=q.top().sec;q.pop();if(vis[x]) continue; if(x==t) return d[t];vis[x]=1;int y; Rep(i,g[x]) if(!vis[y=g[x][i].fir]) if(d[y]>d[x]+g[x][i].sec) d[y]=d[x]+g[x][i].sec,q.push(mp(-d[y],y)); } return d[t]; } db simpson(db l,db r,db vl,db vr,db vm) { db mid=(l+r)/2,lm=(l+mid)/2,rm=(mid+r)/2; db vlm=dijkstra(lm),vrm=dijkstra(rm); db sl=(mid-l)*(vl+vm+4*vlm)/6, sr=(r-mid)*(vm+vr+4*vrm)/6, s=(r-l)*(vl+vr+4*vm)/6; if(gabs(r-l)<eps||gabs(sl+sr-s)<eps) return (sl+sr+s)/2; return simpson(l,mid,vl,vm,vlm)+simpson(mid,r,vm,vr,vrm); } db simpson(db L,db R) { return simpson(L,R,dijkstra(L),dijkstra(R),dijkstra((L+R)/2)); } int main() { n=inn(),m=inn(),s=inn(),t=inn(); rep(i,1,m) u[i]=inn(),v[i]=inn(),x[i]=inn(),y[i]=inn(); return !printf("%lf\n",(double)simpson(0,1)); }