zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    解决UITableView中Cell重用机制导致内容出错的方法总结
    Hdu 1052 Tian Ji -- The Horse Racing
    Hdu 1009 FatMouse' Trade
    hdu 2037 今年暑假不AC
    hdu 1559 最大子矩阵
    hdu 1004 Let the Balloon Rise
    Hdu 1214 圆桌会议
    Hdu 1081 To The Max
    Hdu 2845 Beans
    Hdu 2955 Robberies 0/1背包
  • 原文地址:https://www.cnblogs.com/Leohh/p/7635994.html
Copyright © 2011-2022 走看看