• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
mhy12345
博客园    首页    新随笔    联系   管理    订阅  订阅

Contest 20140923 潛行世界 拓撲排序,期望

潜行世界

  • 查看
  • 提交
  • 统计
  • 提问
总时间限制: 
10000ms
 
内存限制: 
256000kB
描述

HJA和学弟还在旅游中,这次他们来到了潜行世界。潜行世界是一个N个点M条边的有向无环图。每条路对于HJA和学弟都一个吸引指数,我们把它叫做这条边的权值。权值越大,HJA和学弟就越有可能走这条路。假设HJA和学弟现在在点u,点u出发的所有边的权值之和为s,从u到v的边的权值为w,那么他们选择走向v的概率就是。为了使得问题变得更加简单,HJA决定在开始前删掉任意一条边(也可以不删)。当HJA和学弟走到一个没有出边的点时,这次旅行就结束了。HJA想知道,如果他和学弟从零号点出发,他们期望走的长度最长是多少呢?(每条边的长度都为1)

 

输入
第一行两个正整数N、M,代表图的点数和边数。
接下来M行每行三个整数S、E、D,代表S到E有一条权值为D的边。
输出
一行一个实数代表答案,误差不得超过1e-6。(没有spj,有问题就找zhx)
样例输入
4 5
0 1 2
0 2 1
0 3 3
1 3 1
2 3 4
样例输出
2.000000
提示
对于50%的数据,1≤N≤500。
对于100%的数据,1≤N≤10,000,1≤M≤100,000,所有边权不超过103。
来源
zhonghaoxi
這道題在考場上將無向圖與樹搞混了,用樹形DP的思路來做得這道題,上述思路會出現算重的問題。
這道題的正解是預處理計算到每個點的概率,在枚舉刪邊。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<string>
#include<queue>
using namespace std;
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define MAXN 110000
#define MAXV MAXN*2
#define MAXE MAXV*2
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
#define PROB "secretbase"
typedef long long qword;
inline int nextInt()
{
        char ch;
        int x=0;
        bool flag=false;
        do
                ch=getchar(),flag=(ch=='-')?true:flag;
        while(ch<'0'||ch>'9');
        do x=x*10+ch-'0';
        while (ch=getchar(),ch<='9' && ch>='0');
        return x*(flag?-1:1);
}

int n,m;
struct Edge
{
        int np,val;
        Edge *next;
}E[MAXN],*V[MAXV];
int tope=-1;
void addedge(int x,int y,int z)
{
        E[++tope].np=y;
        E[tope].val=z;
        E[tope].next=V[x];
        V[x]=&E[tope];
}
int totw[MAXN];
int el[MAXE][3];
bool vis[MAXN];
queue<int> Q;
int seq[MAXN],tops=-1;
int dego[MAXN];
int degi[MAXN];
double poss[MAXN],g[MAXN];;
int main()
{
        freopen(PROB".in","r",stdin);
        freopen(PROB".out","w",stdout);
        int i,j,k;
        int x,y,z;
        scanf("%d%d",&n,&m);
        for (i=0;i<m;i++)
        {
                scanf("%d%d%d",&x,&y,&z);
                totw[x]+=z;
                addedge(x,y,z);
                dego[x]++;
                degi[y]++;
                el[i][0]=x;
                el[i][1]=y;
                el[i][2]=z;
        }
        memset(vis,0,sizeof(vis));
        for (i=0;i<n;i++)
        {
                if (!degi[i])
                {
                        Q.push(i);
                        vis[i]=true;
                }
        }
        int now;
        Edge *ne;
        while (!Q.empty())
        {
                now=Q.front();
                Q.pop();
                seq[++tops]=now;
                for (ne=V[now];ne;ne=ne->next)
                {
                        if (vis[ne->np])continue;
                        degi[ne->np]--;
                        if (!degi[ne->np])
                        {
                                Q.push(ne->np);
                                vis[ne->np]=true;
                        }
                }
        }
        poss[0]=1;
        for (i=0;i<=tops;i++)
        {
                now=seq[i];
                for (ne=V[now];ne;ne=ne->next)
                {
                        poss[ne->np]+=poss[now]*ne->val/totw[now];
                }
        }
        tope=-1;
        memset(V,0,sizeof(V));
        memset(vis,0,sizeof(vis));
        for (i=0;i<n;i++)g[i]=1e100;
        for (i=0;i<m;i++)
        {
                addedge(el[i][1],el[i][0],el[i][2]);
        }
        for (i=0;i<n;i++)
        {
                if (!dego[i])
                {
                        vis[i]=true;
                        Q.push(i);
                        g[i]=0;
                }
        }
        tops=-1;
        while (!Q.empty())
        {
                now=Q.front();
                Q.pop();
                seq[++tops]=now;
                for (ne=V[now];ne;ne=ne->next)
                {
                        if (vis[ne->np])continue;
                        dego[ne->np]--;
                        if (!dego[ne->np])
                        {
                                Q.push(ne->np);
                                vis[ne->np]=true;
                        }
                }
        }
//        for (i=0;i<=tops;i++)printf("%d ",seq[i]);printf("\n");
        memset(V,0,sizeof(V));
        tope=-1;
        for (i=0;i<m;i++)
        {
                addedge(el[i][0],el[i][1],el[i][2]);
        }
        for (i=0;i<=tops;i++)
        {
                now=seq[i];
                if (!g[now])continue;
                g[now]=0;
                for (ne=V[now];ne;ne=ne->next)
                {
                        g[now]+=g[ne->np]*ne->val/totw[now];
                }
                g[now]+=1;
        }
//        for (i=0;i<n;i++)printf("%lf ",g[i]);
        double delta=-1e100;
        double t;
        double gn;
        for (i=0;i<m;i++)
        {
                if (totw[el[i][0]]==el[i][2])
                {
                        gn=0;
                }else
                        gn=(g[el[i][0]]-(g[el[i][1]]+1)*el[i][2]/totw[el[i][0]])*totw[el[i][0]]/(totw[el[i][0]]-el[i][2]);
                delta=max((gn-g[el[i][0]])*poss[el[i][0]],delta);
        }
        delta=max(0.0,delta);
        printf("%.6lf ",g[0]+delta);
        return 0;
}

 

by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

本博客已停用,新博客地址:http://mhy12345.xyz

posted @ 2014-09-29 23:01  mhy12345  阅读(185)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3