vijos P1966 夜夜的旅游计划

来源:互联网 发布:java最简单小游戏程序 编辑:程序博客网 时间:2024/04/28 00:30

背景

夜夜很贪玩。

描述

威尼斯是著名的水城。由n个岛和m座桥。岛从1到n编号。
夜夜是一名到威尼斯游玩的游客,她觉得每个岛都很有意思。因此她每次都会随机选择一个与当前岛相邻的岛去参观【同一座岛可以重复参观】。每座桥有一个权值At, 走过这座桥需要花费At个单位的时间, 桥可以双向通过。
夜夜初始在1号岛,她希望最终能到n号岛去。
那么夜夜到达n号岛的期望时间是多少呢?
答案保留一位小数。

格式

输入格式

第一行有两个整数n和m,表示岛屿个数与桥的个数。
之后m行,每行有三个整数u,v和At。其中1<=u,v<=n,表示有一座在岛u和岛v之间的桥,其权值为At。

输出格式

输出答案,答案四舍五入保留到一位小数。

样例1

样例输入1[复制]

3 31 2 12 3 13 1 1

样例输出1[复制]

2.0

样例2

样例输入2[复制]

5 41 2 12 3 13 4 14 5 1

样例输出2[复制]

16.0

限制

对于30%的数据
2<=n<=10
对于另外10%的数据
保证数据是一条链
对于另外10%的数据
保证数据是一个环,且1号岛与n号岛相连。
对于100%的数据
2<=n<=200
m<=n(n-1)/2
1<=At<=1000

数据保证每个岛和其余的都是联通的。且图中不存在重边。

每一个测试点时限1秒。




咱自己出的题。。结果自己的程序精度被卡了。。

这题是裸的高斯消元

根据期望的计算方法如下建立方程

for (int i=1;i<n;i++){double siz=G[i].size();mat[i][i]=-siz;for (int j=0;j<G[i].size();j++)mat[i][G[i][j]]=1.0;for (int j=0;j<G[i].size();j++)mat[i][n+1]+=(double)G1[i][j];mat[i][n+1]/=siz;}mat[n][n]=1;

然后你就被卡精度了!!

分析问题所在的话是因为进行了/siz操作

那么怎么办呢?

把所有的方程*siz就可以了

for (int i=1;i<n;i++){double siz=G[i].size();mat[i][i]=-1;for (int j=0;j<G[i].size();j++)mat[i][G[i][j]]=1.0;for (int j=0;j<G[i].size();j++)mat[i][n+1]+=(double)G1[i][j];}mat[n][n]=1;

然后直接上高斯消元即可

最后要调整一下eps。。。嗯就是这样

#include<cstdio>#include<vector>#include<iostream>using namespace std;const int Maxn=2000;double mat[Maxn][Maxn];vector<int> G[Maxn];vector<int> G1[2000];int tot;void gauss(){    int now=1;    for(int i=1;i<=tot;i++){        int j;for(j=now;!mat[j][now]&&j<=tot;j++);        for(int k=1;k<=tot+1;k++)swap(mat[now][k],mat[j][k]);        for(int j=1;j<=tot;j++)            if(j!=now){                double t=mat[j][now]/mat[now][now];                for(int k=1;k<=tot+1;k++)                    mat[j][k]-=t*mat[now][k];            }        now++;    }        for (int i=1;i<=tot;i++) mat[i][tot+1]/=(-mat[i][i]);}int n,m;int main(){//freopen("data.in","r",stdin);//freopen("data.ans","w",stdout);scanf("%d%d",&n,&m);for (int i=1;i<=m;i++){int x,y,t;scanf("%d%d%d",&x,&y,&t);G[x].push_back(y);G[y].push_back(x);G1[x].push_back(t);G1[y].push_back(t);}tot=n;for (int i=1;i<n;i++){double siz=G[i].size();mat[i][i]=-siz;for (int j=0;j<G[i].size();j++){//mat[i][G[i][j]]=1.0/siz;mat[i][G[i][j]]=1.0;//mat[i][G[i][j]]=1.0/(double)G[G[i][j]].size();}for (int j=0;j<G[i].size();j++){mat[i][n+1]+=(double)G1[i][j];//mat[i][G[i][j]]=1.0/(double)G[G[i][j]].size();}//mat[i][n+1]/=siz;}mat[n][n]=1;/*for (int i=1;i<=n;i++){for(int j=1;j<=n+1;j++) cout<<mat[i][j]<<" ";cout<<endl;}*/gauss();//for (int i=1;i<=n;i++){//printf("F[%d]=",i);//cout<<mat[i][n+1]<<endl;//}double eps=0.000001;printf("%.1f\n",mat[1][n+1]+eps);return 0;}


0 0
原创粉丝点击