【codevs2488】绿豆蛙的归宿

 

这个题开始正向拓扑排序,然后各种wa,心灰意冷,找了个题解,和同学研究了半天,甚至曾经一度认为题解是错的。

这个题正向反向应该都无所谓,但是我实在是蒻,打了半天正向都没打过去,最后跟随dalao的步伐走向了反向拓扑

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
using namespace std;
int n,m,x,y,z,head[100010],tail,ru[100010],chu[100010];
bool flag[100010];
double ans[100010];
queue<int>qwq;
struct in
{
    int to,ne,co;
}ter[200020];
inline void build(int f,int l,int c)
{
    ter[++tail]=(in){l,head[f],c},head[f]=tail;
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&x,&y,&z),build(y,x,z),ru[x]++,chu[x]++;//反向建图,因为从1跑不到的点肯定反向建图也跑不到1 
    for(int i=1;i<=n;i++)
        if(!ru[i])//如果原图该点,没有出边(终点)
            qwq.push(i);
    while(!qwq.empty())
    {
        int qaq=qwq.front();qwq.pop();//这里可以换成栈,跑的还更快,虽然我不知道为啥 
        for(int i=head[qaq];i>0;i=ter[i].ne)
        {
            int t=ter[i].to;
            double gai=1.0/chu[t];
            ans[t]+=(ans[qaq]+ter[i].co)*gai;//求期望的必要步骤嘛qwq 
            ru[t]--;
            if(!ru[t])
                qwq.push(t);
        } 
    }
    for(int i=1;i<=n;i++)
    printf("%.2lf ",ans[i]);
    //printf("%.2lf",ans[1]);
}
/*关于这个反向拓扑排序可以的原因
因为每一个点都可以到达终点,所以无论正向反向,所有的从1到n的路径的期望值都不会变
所以正向反向无所谓
为什么要用拓扑排序
因为只有一个点所有到他的边都被走过,关于到它的期望值才算真正确定 
*/ #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
using namespace std;
int n,m,x,y,z,head[100010],tail,ru[100010],chu[100010];
bool flag[100010];
double ans[100010];
queue<int>qwq;
struct in
{
    int to,ne,co;
}ter[200020];
inline void build(int f,int l,int c)
{
    ter[++tail]=(in){l,head[f],c},head[f]=tail;
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&x,&y,&z),build(y,x,z),ru[x]++,chu[x]++;//反向建图,因为从1跑不到的点肯定反向建图也跑不到1 
    for(int i=1;i<=n;i++)
        if(!ru[i])//如果原图该点,没有出边(终点)
            qwq.push(i);
    while(!qwq.empty())
    {
        int qaq=qwq.front();qwq.pop();//这里可以换成栈,跑的还更快,虽然我不知道为啥 
        for(int i=head[qaq];i>0;i=ter[i].ne)
        {
            int t=ter[i].to;
            double gai=1.0/chu[t];
            ans[t]+=(ans[qaq]+ter[i].co)*gai;//求期望的必要步骤嘛qwq 
            ru[t]--;
            if(!ru[t])
                qwq.push(t);
        } 
    }
    for(int i=1;i<=n;i++)
    printf("%.2lf ",ans[i]);
    //printf("%.2lf",ans[1]);
}
/*关于这个反向拓扑排序可以的原因
因为每一个点都可以到达终点,所以无论正向反向,所有的从1到n的路径的期望值都不会变
所以正向反向无所谓
为什么要用拓扑排序
因为只有一个点所有到他的边都被走过,关于到它的期望值才算真正确定 
*/ #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
using namespace std;
int n,m,x,y,z,head[100010],tail,ru[100010],chu[100010];
bool flag[100010];
double ans[100010];
queue<int>qwq;
struct in
{
    int to,ne,co;
}ter[200020];
inline void build(int f,int l,int c)
{
    ter[++tail]=(in){l,head[f],c},head[f]=tail;
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&x,&y,&z),build(y,x,z),ru[x]++,chu[x]++;//反向建图,因为从1跑不到的点肯定反向建图也跑不到1 
    for(int i=1;i<=n;i++)
        if(!ru[i])//如果原图该点,没有出边(终点)
            qwq.push(i);
    while(!qwq.empty())
    {
        int qaq=qwq.front();qwq.pop();//这里可以换成栈,跑的还更快,虽然我不知道为啥 
        for(int i=head[qaq];i>0;i=ter[i].ne)
        {
            int t=ter[i].to;
            double gai=1.0/chu[t];
            ans[t]+=(ans[qaq]+ter[i].co)*gai;//求期望的必要步骤嘛qwq 
            ru[t]--;
            if(!ru[t])
                qwq.push(t);
        } 
    }
    for(int i=1;i<=n;i++)
    printf("%.2lf ",ans[i]);
    //printf("%.2lf",ans[1]);
}
/*关于这个反向拓扑排序可以的原因
因为每一个点都可以到达终点,所以无论正向反向,所有的从1到n的路径的期望值都不会变
所以正向反向无所谓
为什么要用拓扑排序
因为只有一个点所有到他的边都被走过,关于到它的期望值才算真正确定 
*/ 

 

posted @ 2017-10-21 20:31  那一抹落日的橙  阅读(254)  评论(0编辑  收藏  举报