POJ 2240 Arbitrage spfa 判正环

d[i]代表从起点出发可以获得最多的钱数,松弛是d[v]=r*d[u],求最长路,看有没有正环

然后这题输入有毒,千万别用cin 因为是大输入,组数比较多,然后找字符串用strcmp就好,千万不要用map

这题刚开始我T了(用的map),还以为组数很多卡spfa呢,然后我上网看了看都是floyd的,然后我用floyd写了一发,891ms过了

然后我感觉spfa的复杂度也不是很大,就是看有没有正环,所以我觉得可能是map+cin的锅,然后改了一发,用的spfa,47ms过

真是,算了,实质是本蒟蒻经验不足(其实也不是没做过卡输入的)

这是map+cin+floyd

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>
#include<string>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
const int N=35;
const int INF=0x3f3f3f3f;
map<string,int>mp;
double d[N][N];
int n,m;
bool fun(){
    for(int k=1;k<=n;++k)
     for(int i=1;i<=n;++i)
      for(int j=1;j<=n;++j)
       d[i][j]=max(d[i][j],d[i][k]*d[k][j]);
    for(int i=1;i<=n;++i)
     if(d[i][i]>1)return true;
     return false;   
}
int main(){
    int cas=0;
    while(~scanf("%d",&n),n){
       mp.clear();
       for(int i=1;i<=n;++i){
        string t;
        cin>>t;
        mp[t]=i;
       }
       memset(d,0,sizeof(d));
       for(int i=1;i<=n;++i)
        d[i][i]=1;
       scanf("%d",&m);
       while(m--){
         string x,y;
         double r;
         cin>>x>>r>>y;
         d[mp[x]][mp[y]]=r;
       }
       printf("Case %d: ",++cas);
       if(fun())printf("Yes
");
       else printf("No
"); 
    }
}
View Code

这是strcmp+spfa(推荐看这个)

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>
#include<string>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
const int N=35;
const int INF=0x3f3f3f3f;
struct Edge{
  int v,next;
  double r;
}edge[N*N];
int n,m,head[N],tot,cnt[N];
void add(int u,int v,double r){
    edge[tot].v=v;
    edge[tot].r=r;
    edge[tot].next=head[u];
    head[u]=tot++;
}
bool inq[N];
double d[N];
queue<int>q;
bool spfa(int s){
   for(int i=1;i<=n;++i)
     d[i]=cnt[i]=inq[i]=0;
   d[s]=1,++cnt[s],inq[s]=true; 
   while(!q.empty())q.pop();
   q.push(s);
   while(!q.empty()){
    int u=q.front();
      q.pop();
      inq[u]=false;
     for(int i=head[u];~i;i=edge[i].next){
         int v=edge[i].v;
         if(d[u]*edge[i].r>d[v]){
           d[v]=d[u]*edge[i].r;
           if(!inq[v]){
              inq[v]=true;
              if(++cnt[v]>n)return true;
              q.push(v);
           } 
         }

     }
     if(d[s]>1)return true;
   }
   return false;
}
char a[N][100];
int find(char *s){
  for(int i=1;i<=n;++i)
   if(!strcmp(s,a[i]))return i; 
}
int main(){
    int cas=0;
    while(~scanf("%d",&n),n){
       memset(head,-1,sizeof(head)),tot=0;
       for(int i=1;i<=n;++i)
         scanf("%s",a[i]);
       scanf("%d",&m);
       while(m--){
         char s[100];
         double r;
         scanf("%s%lf",s,&r);
         int u=find(s);
         scanf("%s",s);
         int v=find(s);
         add(u,v,r);
       }
       printf("Case %d: ",++cas);
       if(spfa(1))printf("Yes
");
       else printf("No
"); 
    }
}
View Code
原文地址:https://www.cnblogs.com/shuguangzw/p/5317801.html