题意:已知有N种货币以及兑换税率,求是否存在一种兑换方法使钱越来越多。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217
思路:最短路问题,将加法换成乘法,不能使用dij算法,注意这里不能用Dijkstra,因为乘法中小于1相当于加法中的小于0,会形成负环导致WA。
注意点:可能出现起点与终点是同一点的路径(WA了一次)
以下为AC代码:
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
11902281 | 2014-10-18 14:50:28 | Accepted | 1217 | 265MS | 412K | 5545 B | G++ | luminous11 |
//SPFA
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <deque>
#include <list>
#include <cctype>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
struct node
{
string a;
string b;
double tran;
} tmp;
double adj[50][50];
double path[50];
int cnt[50];
int t;
int ke;
bool flag;
string str[30];
void init ()
{
memset ( path, 0, sizeof( path ) );
memset ( cnt, 0, sizeof ( cnt ) );
memset ( adj, 0, sizeof ( cnt ) );
flag = false;
}
void SPFA ( int be, int en )
{
queue<double>p;
p.push( be );
for ( int i = 0; i < t; i ++ )
{
if ( adj[be][i] != 0 )
{
path[i] = adj[be][i];
break;
}
}
while ( ! p.empty() )
{
be = p.front();
p.pop();
for ( int i = 0; i < t; i ++ )
{
if ( path[i] < path[be] * adj[be][i] )
{
path[i] = path[be] * adj[be][i];
p.push( i );
if ( i == en )
{
if ( path[i] > 1.0 )
{
flag = 1;
return;
}
}
}
}
}
}
int main()
{
int ncase = 1;
while ( cin >> t && t )
{
init ( );
for ( int i = 0; i < t; i ++ )
{
cin >> str[i];
}
int k;
cin >> k;
for ( int i = 0; i < k; i ++ )
{
int be, en;
cin >> tmp.a;
cin >> tmp.tran;
cin >> tmp.b;
for ( int j = 0; j < t; j ++ )
{
if ( tmp.a == str[j] )
{
be = j;
}
if ( tmp.b == str[j] )
{
en = j;
}
}
adj[be][en] = tmp.tran;
//cout << be << ' ' << en << ' ' << tmp.tran << endl;
}
for ( int i = 0; i < t; i ++ )
{
SPFA ( i, i );
if ( flag )
{
break;
}
}
if ( flag )
{
cout << "Case " << ncase ++ << ": Yes" << endl;
}
else
{
cout << "Case " << ncase ++ << ": No" << endl;
}
}
return 0;
}
//floyd
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <deque>
#include <list>
#include <cctype>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#define INF -10
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
struct node
{
string a;
string b;
double tran;
} tmp;
double adj[50][50];
int t;
string str[30];
void init ()
{
for ( int i = 0; i < t; i ++ )
{
for ( int j = 0; j <t; j ++ )
{
adj[i][j] = 0;
}
}
for ( int i = 0; i < t; i ++ )
{
adj[i][i] = 1;
}
}
bool floyd ( )
{
for ( int i = 0; i < t; i ++ )
{
for ( int j = 0; j < t; j ++ )
{
for ( int k = 0; k < t; k ++ )
{
adj[j][k] = max ( adj[j][k], adj[j][i] * adj[i][k] );
}
}
}
for ( int i = 0; i < t; i ++ )
{
if ( adj[i][i] > 1.0 )
{
return 1;
}
}
return 0;
}
int main()
{
int ncase = 1;
while ( cin >> t && t )
{
init ( );
for ( int i = 0; i < t; i ++ )
{
cin >> str[i];
}
int k;
cin >> k;
for ( int i = 0; i < k; i ++ )
{
int be, en;
cin >> tmp.a;
cin >> tmp.tran;
cin >> tmp.b;
for ( int j = 0; j < t; j ++ )
{
if ( tmp.a == str[j] )
{
be = j;
}
if ( tmp.b == str[j] )
{
en = j;
}
}
adj[be][en] = tmp.tran;
}
if ( floyd () )
{
cout << "Case " << ncase ++ << ": Yes" << endl;
}
else
{
cout << "Case " << ncase ++ << ": No" << endl;
}
}
return 0;
}
//数据生成器
int main()
{
freopen ( "data.in", "w", stdout );
srand((unsigned)time(NULL));
int k = 0;
while ( k ++ < 50 )
{
int n = rand() % 23 + 3;
cout << n << endl;
char ch = 'a';
char str[30];
for ( int i = 0; i < n; i ++ )
{
str[i] = ch + i;
cout << str[i] << endl;
}
int k = rand() % ( n * ( n - 1 ) );
cout << k << endl;
for ( int i = 0; i < k; i ++ )
{
cout << str[rand () % n] << ' ';
cout << rand () % 100 << '.' << rand() % 99 + 1 << ' ';
cout << str[rand () % n];
cout << endl;
}
}
}