Hdu1217 这题很棒突破了传统的最短路的,但思想都是一样的,一道挺新颖的题目。
用了两种方法解 一是 Spfa 二是Floyd(-_-终于能用Floyd了,一直没机会)
Spfa Floyd
不过在用Spfa算法时,在处理环的问题网上的题解是在队列循环中加上if(dis[开始]>1.0) return ture 而我是在处理完队列循环后再加这个判断的,发现时间竟然查了10几倍,感觉好神奇。(PS:前者还有个好处,不用处理环的问题)
Spfa
#include<iostream> #include<algorithm> #include<stdlib.h> #include<string.h> #include<math.h> #include<string> #include<vector> #include<queue> #include<list> using namespace std; typedef long long lld; typedef unsigned int ud; #define Inf INT_MAX/2//int最大 #define Min(x,y) (x)<(y)?(x):(y) #define Max(x,y) (x)>(y)?(x):(y) #define PQ priority_queue #define Q queue #define N 33 int n,m; struct Node { int v,next; double w; }edge[N*N]; double dis[N]; int mark[N],head[N],cnt[N]; char str[N*N][N]; char buff[N]; int GetCur(char *s) { for(int i=1;i<=n;i++) if(strcmp(s,str[i])==0) return i; return -1; } bool Spfa(int s) { memset(dis,0,sizeof dis); memset(mark,0,sizeof mark); memset(cnt,0,sizeof cnt); dis[s]=1.0; mark[s]=1; Q<int> q; q.push(s); while(!q.empty()) { int e=q.front(); q.pop(); mark[e]=0; for(int i=head[e];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dis[e]*edge[i].w>dis[v]) { dis[v]=dis[e]*edge[i].w; if(!mark[v]) { q.push(v); mark[v]=1; if(++cnt[v]>n) break; } } } } if(dis[s]>1.0) return true; return false; } int main() { int cas=1; while(scanf("%d",&n)&&n) { memset(head,-1,sizeof head); for(int i=1;i<=n;i++) scanf("%s",str[i]); scanf("%d",&m); for(int i=1;i<=m;i++) { int u,v; double w; scanf("%s",buff); u=GetCur(buff); scanf("%lf%s",&w,buff); v=GetCur(buff); edge[i].v=v; edge[i].w=w; edge[i].next=head[u]; head[u]=i; } int find=false; for(int i=1;i<=n;i++) { if(Spfa(i)) { find=true; break; } } printf("Case %d: ",cas++); if(find) printf("Yes\n"); else printf("No\n"); } return 0; }Floyd
#include<iostream> #include<algorithm> #include<stdlib.h> #include<string.h> #include<math.h> #include<string> #include<vector> #include<queue> #include<list> using namespace std; typedef long long lld; typedef unsigned int ud; #define Inf INT_MAX/2//int最大 #define Min(x,y) (x)<(y)?(x):(y) #define Max(x,y) (x)>(y)?(x):(y) #define PQ priority_queue #define Q queue #define N 33 double map[N][N]; char str[N*N][N]; char a[N],b[N]; int n,m; int u,v; double w; int GetCur(char *s) { for(int i=1;i<=n;i++) if(strcmp(s,str[i])==0) return i; return -1; } void Floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(map[i][k]*map[k][j]>map[i][j]) map[i][j]=map[i][k]*map[k][j]; } int main() { int cas=1; while(scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j) map[i][j]=1.0; else map[i][j]=0.0; } for(int i=1;i<=n;i++) scanf("%s",str[i]); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%s%lf%s",a,&w,b); u=GetCur(a); v=GetCur(b); map[u][v]=w; } Floyd(); int find=false; for(int i=1;i<=n;i++) if(map[i][i]>1.0) find=true; printf("Case %d: ",cas++); if(find) printf("Yes\n"); else printf("No\n"); } return 0; } /* 3 USDollar BritishPound FrenchFranc 3 USDollar 0.5 BritishPound BritishPound 10.0 FrenchFranc FrenchFranc 0.21 USDollar 3 USDollar BritishPound FrenchFranc 6 USDollar 0.5 BritishPound USDollar 4.9 FrenchFranc BritishPound 10.0 FrenchFranc BritishPound 1.99 USDollar FrenchFranc 0.09 BritishPound FrenchFranc 0.19 USDollar 0 */