Calabash(葫芦娃)

这题考试的时候并没有想出来……还是自己太弱了。

当时的想法是如何找到一条最短而且经过点最多的路,之后就一直卡在这上面出不来了……

但后来发现并不需要这样,因为我们要求的是……路径长和经过点数的比值,所以我们可以选择在原图中跑spfa或者dij,每次走到一个新的点,就把当前点数设置为转移过来的那个地方的点数+1,之后直接判断如果当前的比值更小就更新即可。

这样是可以保证正确性的,因为它肯定会取到所有的情况,即使当前的情况并不是很优秀,它将来一定会在某个位置被更优秀的情况所取代。

然后就可以了……这题不需要瞎考虑怎么记录路径上的点数……自己就是死在这里……

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<set>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')

using namespace std;
typedef long long ll;
const int M = 100005;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') op = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
    }
    return ans * op;
}

struct edge
{
    int next,to,from;
    double v;
}e[M];

int n,m,head[1005],x,y,ecnt;
double z,ans,dis[1005],dep[1005];

set<pair<double,int> > q;
set<pair<double,int> > :: iterator it;

void add(int x,int y,int z)
{
    e[++ecnt].to = y;
    e[ecnt].v = z;
    e[ecnt].from = x;
    e[ecnt].next = head[x];
    head[x] = ecnt;
}

void dijk(int s)
{
    q.insert(make_pair(dis[s],s));
    dis[s] = 0,dep[s] = 1;
    while(!q.empty())
    {
        pair<double,int> k = *(q.begin());
        q.erase(q.begin());
        int g = k.second;
        for(int i = head[g];i;i = e[i].next)
        {
            double d1 = dis[g] + e[i].v;
            double d2 = dep[g] + 1;
            if(d1 / d2 < dis[e[i].to] / dep[e[i].to] || (dis[e[i].to] == 0 && dep[e[i].to] == 0)) 
            {
                dis[e[i].to] = d1,dep[e[i].to] = d2;//在这里判断是否符合并且更新
                q.insert(make_pair(d1/d2,e[i].to));
            }
        }
    }
}

int main()
{
//    freopen("calabash.in","r",stdin);
//    freopen("calabash.out","w",stdout);
    n = read(),m = read();
    rep(i,1,n) dis[i] = 999999999;
    rep(i,1,m) x = read(),y = read(),scanf("%lf",&z),add(x,y,z);
    dijk(1);
    printf("%.3lf\n",dis[n] / dep[n]);
    return 0;
}

 

posted @ 2018-09-07 14:39  CaptainLi  阅读(500)  评论(0编辑  收藏  举报