hdu1217

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

*/

你可能感兴趣的:(算法,floyd,SPFA)