BZOJ2707 [SDOI2012]走迷宫

来源:互联网 发布:爱淘宝红包不中 编辑:程序博客网 时间:2024/04/30 21:26

设f[i]表示从第i个点走到终点的期望,d[i]表示i的出度,j是第i个点能走到的点

则f[i]=sigma (f[j]+1)/d[i]

在数据范围小的情况下,我们可以高斯消元求出f数组

由于本题中每个边双大小<=100,把边双缩点之后的图是有拓扑序的,所以我们可以按拓扑序求,每个边双内高斯消元

不过这复杂度上限不是100^4的么……反正能过……

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<queue>#include<map>#include<bitset>#include<stack>#include<vector>#include<set>using namespace std;#define MAXN 10010#define MAXM 1000010#define INF 1000000000#define MOD 1000000007#define ll long long#define eps 1e-8struct vec{int to;int fro;};struct G{vec mp[MAXM];int tai[MAXN],cnt;inline void be(int x,int y){mp[++cnt].to=y;mp[cnt].fro=tai[x];tai[x]=cnt;}void dfs(int x);void build();void cal(int x);void get(int x);};G g,ng;bool ist[MAXN];int st[MAXN],tp;int dfn[MAXN],ndf[MAXN],low[MAXN],tim;int bel[MAXN],siz[MAXN],tot;int n,m;vector<int>ps[MAXN];bool vis[MAXN],VIS[MAXN];double f[MAXN];int d[MAXN];int S,T;int lst[110][110];double a[110][110];void G::dfs(int x){int i,y;dfn[x]=low[x]=++tim;ist[st[++tp]=x]=1;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;if(!dfn[y]){dfs(y);low[x]=min(low[x],low[y]);}else if(ist[y]){low[x]=min(low[x],dfn[y]);}}if(low[x]==dfn[x]){int t=0;tot++;while(t!=x){ist[t=st[tp--]]=0;siz[bel[t]=tot]++;ps[tot].push_back(t);}}}void G::build(){int i,x,y;for(x=1;x<=n;x++){for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;if(bel[x]!=bel[y]){ng.be(bel[x],bel[y]);}}}}void jud(int x,int y){if(lst[x][y]!=tim){a[x][y]=0;}lst[x][y]=tim;}void G::get(int x){int i,y;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;if(VIS[y]){jud(dfn[x],tot+1);a[dfn[x]][tot+1]+=1.0*(f[y]+1)/d[x];}else{jud(dfn[x],dfn[y]);jud(dfn[x],tot+1);a[dfn[x]][tot+1]+=1.0/d[x];a[dfn[x]][dfn[y]]-=1.0/d[x];}}}void gs(){int i,j,k;for(i=1;i<=tot;i++){ jud(i,i);if(fabs(a[i][i])<eps){for(j=i+1;j<=tot;j++){jud(j,i);if(fabs(a[j][i]>eps)){for(k=1;k<=tot+1;k++){jud(i,k);jud(j,k);swap(a[i][k],a[j][k]);}}}}if(fabs(a[i][i]>eps)){for(j=1;j<=tot;j++){if(i!=j){jud(j,i);double t=a[j][i]/a[i][i];for(k=1;k<=tot+1;k++){jud(i,k);jud(j,k);a[j][k]-=t*a[i][k];}}}}}}void G::cal(int x){int i,y;if(vis[x]){return ;}vis[x]=1;for(i=tai[x];i;i=mp[i].fro){cal(mp[i].to);}tot=0;tim++;for(i=0;i<ps[x].size();i++){ndf[++tot]=ps[x][i];dfn[ps[x][i]]=tot;jud(tot,tot);a[tot][tot]=1;}for(i=0;i<ps[x].size();i++){g.get(ps[x][i]);}gs();for(i=1;i<=tot;i++){jud(i,i);if(fabs(a[i][i])<eps){printf("INF\n");exit(0);}f[ndf[i]]=a[i][tot+1]/a[i][i];VIS[ndf[i]]=1;}}int main(){int i,x,y;scanf("%d%d%d%d",&n,&m,&S,&T);for(i=1;i<=m;i++){scanf("%d%d",&x,&y);if(x!=T){g.be(x,y);d[x]++;}}g.dfs(S);for(i=1;i<=n;i++){if(i!=T){if(dfn[i]&&(!d[i])){printf("INF\n");return 0;}}else{if(!dfn[i]){printf("INF\n");return 0;}}}g.build();vis[bel[T]]=1;VIS[T]=1;ng.cal(bel[S]);printf("%.3lf\n",f[S]);fclose(stdin);fclose(stdout);return 0;}/**/


1 0
原创粉丝点击