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;
    }
  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/12432088.html
Copyright © 2011-2022 走看看