URAL 1934 最短路变形

DES:给出起点和终点。给出所有小岛的编号。所有路径的起始点。和遇到怪物的概率。要求在最短路的条件下维护遇见怪物的概率最小的路径。就是用 SPFA算法。每条路的权值设为1。最短路即为途径的岛数最少。同时要用pre数组维护每个点的前驱。最后递归输出所走路径。把p变为不遇见怪物的概率, 即为维护p最大。就是把原来的SPFA里的判断多加一条,如果权值相等判断概率,选择概率大的一条。

注意。这是无向图。本来觉得没有影响。很幸福的WA了。确实是。给你a->b的,就代表可以从b->a。而不是简单的可以往返。

不知道用邻接表和邻接矩阵时间差大不大。这里用了邻接表

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#include<queue>
#define N 100010
#define inf 0x1f1f1f1f

int low[N]; //存储源点到每个顶点的最短距离值
bool in_que[N]; //标记一个点是否已在队列中
int cnt[N]; //记录每个点的入队次数,来判断是否出现负环
int pre[N]; // 记录每个点的前驱。即记录源点到每个点的最短路径本身。
int head[N]; //邻接矩阵的表头节点
double p[N]; //存储最短路的情况下。到每个点的p最大。
int n, m;
int h;
bool flag = true;

struct Edge
{
    int v, w, next;
    double p;
}edge[N<<1];

void addEdge(int a, int b, double c)
{
     edge[h].v = b;
     edge[h].w = 1;
     edge[h].p = c;
     edge[h].next = head[a];
     head[a] = h++;
}

void spfa(int s)
{
     for (int i=0; i<=n; ++i)
     {
         p[i] = 0;
         low[i] = inf;
     }
     memset(pre, -1, sizeof(pre));
     memset(in_que, 0, sizeof(in_que));
     queue<int>q;
     in_que[s] = 1;
     low[s] = 1;
     p[s] = 1; //没有怪物
     q.push(s);

     while(!q.empty())
     {
         int x = q.front();
         q.pop();
         in_que[x] = 0;
         for (int i=head[x]; i!=-1; i=edge[i].next)
         {
             int v = edge[i].v;
             if (low[v] > low[x]+1)
             {
                low[v] = low[x] + 1;
                p[v] = p[x]*edge[i].p;
                pre[v] = x;
                if (!in_que[v])
                {
                    in_que[v] = 1;
                    q.push(v);
                }
             }
             else if (low[v] == low[x] + 1)
             {
                 if (p[v] < p[x]*edge[i].p)
                 {
                     p[v] = p[x]*edge[i].p;
                     pre[v] = x;
                     if (!in_que[v])
                     {
                         in_que[v] = 1;
                         q.push(v);
                     }
                 }
             }
         }
     }
     return;
}

void output(int r)
{
    if (pre[r] != -1) output(pre[r]);
    if (flag) flag = false;
    else putchar(‘ ‘);
    printf("%d", r);
}

int main()
{
    int s, t;
    int a, b;
    double c;
    while(~scanf("%d%d", &n, &m))
    {
        scanf("%d%d", &s, &t);
        h = 0;
        memset(head, -1, sizeof(head));
        for (int i=0; i<m; ++i)
        {
            scanf("%d%d%lf", &a, &b, &c);
            c = (1-c/100);
            addEdge(a, b, c);
            addEdge(b, a, c);
        }
        spfa(s);
        printf("%d %.6lf\n", low[t], 1-p[t]);
        flag = true;
        output(t);
        puts("");
    }
    return 0;
}

时间: 2024-10-13 03:32:48

URAL 1934 最短路变形的相关文章

URAL 1934 Black Spot --- 简单最短路变形

边权为1,在维护最短路的同时维护p值最小,我直接存的(1-p),即不遇见的概率,要使得这个值最大. #include <iostream> #include <cstdlib> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #includ

UESTC 915 方老师的分身II --最短路变形

即求从起点到终点至少走K条路的最短路径. 用两个变量来维护一个点的dis,u和e,u为当前点的编号,e为已经走过多少条边,w[u][e]表示到当前点,走过e条边的最短路径长度,因为是至少K条边,所以大于K条边的当做K条边来处理就好了.求最短路的三个算法都可以做,我这里用的是SPFA,比较简洁. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #incl

zoj 1655 Transport Goods (最短路变形)

Transport Goods Time Limit: 2 Seconds      Memory Limit: 65536 KB The HERO country is attacked by other country. The intruder is attacking the capital so other cities must send supports to the capital. There are some roads between the cities and the

zoj1655 最短路变形

题意:HERO过的首都需要货物,需要从其他的城市吧货物送到首都,每条道路都会需要消耗一定比例的货物,问最多能送多少货物到首都. 思路:如果每个点的比例是1,到达首都的比例就是经过的路径的(1-消耗比)的乘积,反正是无向的,所以可以反过来推,首都的货物比是1,而到达每座 城市的货物就是所经过的路径(1-消耗比)的乘积,则由此可见,我们可以求首都到任意城市的最大比值:最后把每个点的最大比值乘以每个点的货物加起来 即是结果. #include<stdio.h> #include<string.

HN0I2000最优乘车 (最短路变形)

HN0I2000最优乘车 (最短路变形) [试题]为了简化城市公共汽车收费系统,某城市决定对大部分的公共汽车都采用一票制,但由于某些公共汽车所经过的停车站太多和路途太长,就采用两票或多票制.经过这种票制改革后,人们坐公共汽车从一个站到另一个站时,就不得不选择一个好的乘车方案,以使他们的乘车费用最低. 为了方便于求出最佳的乘车方案,我们假设: l  采用一票制的公共汽车,无论从哪个站上车到那个站下车,乘该公共汽车的费用为1(费用单位). l  采用多票制的公共汽车,将设立某些站为关键站:那么,如果

POJ 1797 Heavy Transportation (最短路变形)

Heavy Transportation Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 20364   Accepted: 5401 Description Background Hugo Heavy is happy. After the breakdown of the Cargolifter project he can now expand business. But he needs a clever man

HDOJ find the safest road 1596【最短路变形】

find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9033    Accepted Submission(s): 3173 Problem Description XX星球有非常多城市,每一个城市之间有一条或多条飞行通道,可是并非全部的路都是非常安全的,每一条路有一个安全系数s,s是在 0 和

HDU 4318 图论之最短路变形

点击打开链接 题意:看样例说把,一共4个点,接下来输入一个数,代表当前点连接的点的数量,然后那几个点,样例里面就是1->2消耗50%的能量,1->3消耗70%的能量,2->1消耗30%的能量,2->4消耗20%的能量,一次类推,最后一行输入起始位置,重点位置,开始时的能量,问从起点走到终点,消耗的能量最少. 思路:很明显的最短路变形,我们可以将求出从起点到终点剩余的最多的能量,用总能量减去它,就是消耗的最少的能量,这就好办了,将最短路改成最长路即可,但是每次比较时就是比较乘积而不是

URAL 1934 spfa算法

D - Black Spot Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice URAL 1934 Description Bootstrap: Jones's terrible leviathan will find you and drag the Pearl back to the depths and you along with it.