zoukankan      html  css  js  c++  java
  • 【FZYZOJ】细菌 题解(最短路)

    题目描述

    为了研究一种新型细菌(称它为S型细菌)的性质,Q博士将S型细菌放在了一个犹如迷宫一般的通道面前,迷宫中N个站点,每个站点之间以一种单向通道的形式连接,当然,也有可能某两个站点之间是互不联通的,但是保证S型细菌不会走了一段又绕回原处。

    在迷宫中,1号点为入口,N号点为出口。S型细菌被放在了入口,它们在行进过程中只能选择一条通道前进,并要求通过某些通道到达出口。每经过一条通道的时间为1S,而细菌繁殖的速度为每秒多一倍。

    为了更好地探究其性质,Q博士在沿途设置了一些利于其生长的培养液和限制其繁殖的青霉素,S型细菌的数量将因此而增加或者减少一定个数(当然,增减是在其繁殖之后计算)。

    现在告诉你通道的连接情况和沿途Q博士设置的条件,Q博士想知道,至少应该放多少个细菌在入口,才能保证有细菌能够从出口出来?

    输入格式

    第一行为一个整数N(3 ≤ N ≤ 100),下面跟着的第i行第j个数为F[i,j](绝对值不超过10000的整数),表示第I个点到第J个点沿途中细菌增加或减少的个数。若F[I,J]=0则表示此路不通。

    输出格式

    一个正整数,表示至少需要多少个细菌放在入口。

    思路:使用spfa,不断迭代更新。

    //采取逆向思维,从n倒着搜;
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    struct node
    {
        int next,to,dis;
    }edge[50005];
    int head[50005],n,cnt;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void add(int from,int to,int dis)
    {
        edge[++cnt].next=head[from];
        edge[cnt].to=to;
        edge[cnt].dis=dis;
        head[from]=cnt;
    }
    int dis[105],vis[105];//dis[i]即从i到n的所需最少的细菌数
    void work()
    {
        queue<int> q;
        dis[n]=1;vis[n]=1;q.push(n);
        while(!q.empty())
        {
            int now=q.front();q.pop();vis[now]=0;
            for (int i=head[now];i;i=edge[i].next)
            {
                int to=edge[i].to;
                if (dis[to]>max((long long)1,(dis[now]+edge[i].dis+1)/2))
                {
                    dis[to]=max((long long)1,(dis[now]+edge[i].dis+1)/2);
                    if (!vis[to])
                    {
                        q.push(to);
                        vis[to]=1;
                    }
                }
                
            }
        }
    }
    signed main()
    {
        n=read();
        for (int i=1;i<=n;i++) dis[i]=0x3f3f3f3f;
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
            {
                int d=read();
                if (d!=0) add(j,i,-d);//反向存图
            }
        work();
        printf("%ld",dis[1]);
        return 0;
    }
  • 相关阅读:
    安卓目录分析——MainActivity.java和activity_main.xml
    安卓目录理解 —— AndroidMainifest.xml
    安卓教程列表
    安卓目录介绍
    ideal 安卓环境搭建
    ideal 2019激活 方法
    binding.gyp not found 安装java npm 报错
    vue-cli脚手架打包页面空白
    .java文件转为.class文件转jar包
    前端框架Vue自学之Vue基础语法(二)
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/12432088.html
Copyright © 2011-2022 走看看