• BZOJ 2019 [Usaco2009 Nov]找工作:spfa【最长路】【判正环】


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2019

    题意:

      奶牛们没钱了,正在找工作。农夫约翰知道后,希望奶牛们四处转转,碰碰运气。

      而且他还加了一条要求:一头牛在一个城市最多只能赚D(1 <= D <= 1,000)美元,然后它必须到另一座城市工作。当然,它可以在别处工作一阵后又回来原来的城市再最多赚D美元。而且这样往往返返的次数没有限制。

      城市间有P (1 <= P <= 150)条单向路径连接,共有N(2 <= N <= 220)座城市,编号1..N. 贝希当前处在城市S (1 <= S <= N)。路径 i 从城市A[i]到城市B[i](1 <= A[i] <= N, 1 <= B[i] <= N),在路径上行走不用花任何费用。

      为了帮助贝希,约翰让它使用他的私人飞机服务。这项服务有F条(1 <= F <= 350)航线,每条航线是从城市J[i]飞到另一座城市K[i](1 <=J[i] <= N, 1 <= K[i] <= N),费用是T[i] (1 <= T[i] <= 50,000)美元。

      如果贝希手中如果没有现钱,可以用以后赚的钱来付机票钱。

      贝希可以选择任何时候,在任何城市退休。

      如果在工作时间上不作限制,贝希总共可以赚多少钱呢?如果赚的钱也不会出现限制,就输出-1。

    题解:

      spfa找最长路。

      如果有点入队超过n次,则存在正环,return -1。

      建边:

        (1)对于城市间的道路,边权设为D。

        (2)对于航线,边权设为D - T[i]。

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <vector>
      5 #include <queue>
      6 #define MAX_N 250
      7 
      8 using namespace std;
      9 
     10 struct Edge
     11 {
     12     int dest;
     13     int len;
     14     Edge(int _dest,int _len)
     15     {
     16         dest=_dest;
     17         len=_len;
     18     }
     19     Edge(){}
     20 };
     21 
     22 int n,p,f,d,s;
     23 int ans;
     24 int dis[MAX_N];
     25 int cnt[MAX_N];
     26 bool vis[MAX_N];
     27 vector<Edge> edge[MAX_N];
     28 queue<int> q;
     29 
     30 void read()
     31 {
     32     cin>>d>>p>>n>>f>>s;
     33     int a,b,c;
     34     for(int i=0;i<p;i++)
     35     {
     36         cin>>a>>b;
     37         edge[a].push_back(Edge(b,d));
     38     }
     39     for(int i=0;i<f;i++)
     40     {
     41         cin>>a>>b>>c;
     42         edge[a].push_back(Edge(b,d-c));
     43     }
     44 }
     45 
     46 int get_front()
     47 {
     48     int now=q.front();
     49     q.pop();
     50     vis[now]=false;
     51     return now;
     52 }
     53 
     54 void insert(int now)
     55 {
     56     if(vis[now]) return;
     57     q.push(now);
     58     vis[now]=false;
     59     cnt[now]++;
     60 }
     61 
     62 int spfa(int start)
     63 {
     64     memset(dis,0x80,sizeof(dis));
     65     memset(cnt,0,sizeof(cnt));
     66     memset(vis,false,sizeof(vis));
     67     insert(start);
     68     dis[start]=d;
     69     int res=d;
     70     while(!q.empty())
     71     {
     72         int now=get_front();
     73         for(int i=0;i<edge[now].size();i++)
     74         {
     75             Edge temp=edge[now][i];
     76             if(dis[temp.dest]<dis[now]+temp.len)
     77             {
     78                 dis[temp.dest]=dis[now]+temp.len;
     79                 insert(temp.dest);
     80                 if(cnt[temp.dest]>n) return -1;
     81                 res=max(res,dis[temp.dest]);
     82             }
     83         }
     84     }
     85     return res;
     86 }
     87 
     88 void solve()
     89 {
     90     ans=spfa(s);
     91 }
     92 
     93 void print()
     94 {
     95     cout<<ans<<endl;
     96 }
     97 
     98 int main()
     99 {
    100     read();
    101     solve();
    102     print();
    103 }
  • 相关阅读:
    HTCVive摄像头的一些好玩的现象
    AI之A*算法
    C#预处理器指令之#define/#undefine/#if/#elif/#else/#endif
    AI之有限状态机
    Unity之动态加载场景资源
    Canvas
    DFGUI之界面文字显示异常
    Unity Application
    AI:确定性AI
    php正则表达式
  • 原文地址:https://www.cnblogs.com/Leohh/p/7635994.html
Copyright © 2020-2023  润新知