• [ An Ac a Day ^_^ ][kuangbin带你飞]专题四 最短路练习 POJ 2240 Arbitrage spfa求负环


    题意就是问倒腾外币能不能升值

    不用spfa 用其他的最短路算法也可以

    松弛条件换成dist[v]<dist[u]*e[u][i].value

    当然 貌似只有spfa有这个坑……

    有A  (value>1.0) A 这种情况……我的天

    用Dij Floyd都只用判断如果松弛到了自己 那么一定有环 直接跳出就行

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<string>
      7 #include<ctime>
      8 #include<map>
      9 #include<set>
     10 #include<vector>
     11 #include<queue>
     12 #include<cstdlib>
     13 #include<cassert>
     14 #include<sstream>
     15 #include<stack>
     16 #include<list>
     17 #include<bitset>
     18 #define cl(a,b) memset(a,b,sizeof(a))
     19 #define debug(x) cerr<<#x<<"=="<<(x)<<endl
     20 using namespace std;
     21 typedef long long ll;
     22 
     23 const int maxn=1e2+10;
     24 
     25 struct edge
     26 {
     27     int v;
     28     double value;
     29     edge(int _v=0,double _value=0):v(_v),value(_value) {}
     30 };
     31 
     32 map<string,int>mp;
     33 vector<edge>e[maxn];
     34 int n,m;
     35 bool vis[maxn],ok;
     36 int cnt[maxn];
     37 double dist[maxn];
     38 
     39 void addedge(int u,int v,double w)
     40 {
     41     e[u].push_back(edge(v,w));
     42 }
     43 
     44 void init()
     45 {
     46     ok=false;
     47     mp.clear();
     48     for(int i=0;i<maxn;i++) e[i].clear();
     49 }
     50 
     51 bool spfa(int start)
     52 {
     53     cl(vis,false),cl(dist,0),cl(cnt,0);
     54     //注意dist[start]初始化是1
     55     vis[start]=true,dist[start]=1.0,cnt[start]=1;
     56     queue<int>q;
     57     while(!q.empty()) q.pop();
     58     q.push(start);
     59     while(!q.empty())
     60     {
     61         int u=q.front();
     62         q.pop();
     63         vis[u]=false;
     64         for(int i=0; i<e[u].size(); i++)
     65         {
     66             int v=e[u][i].v;
     67             if(dist[v]<dist[u]*e[u][i].value)
     68             {
     69                 dist[v]=dist[u]*e[u][i].value;
     70                 if(!vis[v])
     71                 {
     72                     vis[v]=true;
     73                     q.push(v);
     74                     cnt[v]++;
     75                     if(cnt[v]==n) return true;
     76                 }
     77                 else if(dist[start]>1.0) return true;//特判一下
     78             }
     79         }
     80     }
     81     return false;
     82 }
     83 
     84 int main()
     85 {
     86 //    freopen("in.txt","r",stdin);
     87     int cas=1;
     88     while(~scanf("%d",&n)&&n)
     89     {
     90         init(); //记得初始化
     91         for(int i=0; i<n; i++)
     92         {
     93             string place;
     94             cin>>place;
     95             mp[place]=i;
     96         }
     97         scanf("%d",&m);
     98         for(int i=0; i<m; i++)
     99         {
    100             string place1,place2;
    101             double value;
    102             cin>>place1>>value>>place2;
    103             addedge(mp[place1],mp[place2],value);
    104             //无限WA之后加了下面这句就AC了 T_T
    105             if(mp[place1]==mp[place2]&&value>1.0) ok=true;
    106         }
    107         for(int i=0;i<n&&!ok;i++) ok=spfa(i);
    108         printf("Case %d: %s
    ",cas++,ok?"Yes":"No");//注意是Yes 不是YES
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    sipp3.6对freeswitch进行压力测试
    随机四则运算
    大一暑假第八周周进度总结报告
    大一暑假第七周周进度总结报告
    学生信息管理系统java测试报告
    原码、反码、补码解读
    大一暑假第六周周进度总结报告
    01Java方法
    00java语法基础和课后实践
    验证码和判断回文(递归)
  • 原文地址:https://www.cnblogs.com/general10/p/6348039.html
Copyright © 2020-2023  润新知