POJ 2240 最长路 枚举
题意:
问给你一些货币兑换利率,利用这些汇率能否实现其原有货币增直。
算法:
1.肯定是个回路,不是回路输出No,而且这个回路是最长的,可以用SPFA求最长路,并判断是否构成回路。
2.问题是不知到哪个是源点,也就是所有点得都有可能是源点,枚举所有点为源点,求N次SPFA(N<=30),构造一个货币初始直,如1.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<map> #include<iostream> #include<string> #include<queue> using namespace std; double mp[40][40], dis[100], vis[200]; int N, visit[100]; const int inf = 0x7f7f7f7f; map<string, int>hash; int T; struct node { int ID; double dis; }; int SPFA(int t) { for( int i = 1; i <= N; i++) { visit[i] = 0; dis[i] = 0; vis[i] = 0; } queue<node>q; node p; p.ID = t; p.dis = 1; vis[t] = 1; dis[t] = 1; q.push(p); while( !q.empty() ) { p = q.front(); q.pop(); int x = p.ID; visit[x] = 0; if( p.dis != dis[x] ) continue; for( int i = 1; i <= N; i++) { if( dis[i] < dis[x] * mp[x][i] && mp[x][i] != inf) { dis[i] = dis[x] * mp[x][i]; if( !visit[i] ) { p.ID = i; p.dis = dis[i]; visit[i] = 1; q.push(p); vis[i]++; if( vis[t] >= N ) { if( dis[t] > 1 ) printf("Yes\n"); return 1; } } } } } return 0; } int main( ) { int M; T = 1; while( scanf("%d",&N), N ) { string str, sts; double rate; for( int i = 1; i <= N; i++) for( int j = 1; j <= N; j++) mp[i][j] = ( i == j ) ? 0 : inf; for( int i = 1; i <= N; i++) { cin>>str; hash[str] = i; } scanf("%d",&M); for( int i = 1; i <= M; i++) { cin>>str>>rate>>sts; mp[hash[str]][hash[sts]] = rate; } printf("Case %d: ",T++); int f = 0; for( int i = 1; i <= N; i++) if( SPFA(i) ) { f = 1; break; } if( !f ) printf("No\n"); } return 0; }
posted on 2012-07-12 09:03 more think, more gains 阅读(158) 评论(0) 编辑 收藏 举报