您的位置:首页 > 其它

uva 104(变形floyd)

2013-12-10 01:54 417 查看
题意:有若干种货币,并给出其互相交换的汇率,问能不能找到一个小于n的环使起始点的货币交换之后增长超过1%。

思路:这道题坑了两个小时,一开始看他数据量比较小才20就想用搜索剪枝,后来仔细算了一下还是会超时的,再后来就去看解题报告了。果断想的方向就错了,其实是动态规划状态一看就知道该怎么写了=。=和floyd很像的。dis[i][j][k]表示从i到j交换k次所获得的最大收益。然后四重循环每次枚举中间结点v并从dis[i][v][k-1]转移过来。别忘了转的时候要记录路径。算好之后从1-k扫描一有超过1.01就打印路径即可。

代码如下:(我写的比较长0.0)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <vector>
#define INF 500001
#define LEN 110

using namespace std;

int n, path[LEN][LEN][LEN];
double Map[LEN][LEN], dis[LEN][LEN][LEN];

void floyd()
{
memset(dis, 0, sizeof dis);
memset(path, 0, sizeof path);
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
dis[i][j][1] = Map[i][j];
path[i][j][1] = i;
}
}
for(int k=2; k<=n; k++){
for(int v=1; v<=n; v++){
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(dis[i][j][k]<dis[i][v][k-1]*dis[v][j][1]){
dis[i][j][k] = dis[i][v][k-1]*dis[v][j][1];
path[i][j][k] = v;
}
}
}
}
}
}

void print(int x, int y, int k){
if(k==1)printf("%d", path[x][y][k]);
else{
print(x, path[x][y][k-1], k-1);
printf(" %d", y);
}
}

int main()
{
//    freopen("in.txt", "r", stdin);

while(scanf("%d", &n)!=EOF){
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(i==j){Map[i][j] = 0;continue;}
scanf("%lf", &Map[i][j]);
}
}
floyd();
int f = 0, pos;
for(int k=1; k<=n; k++){
for(int i=1; i<=n; i++){
if(dis[i][i][k] >= 1.01){
f = 1;pos = i;break;
}
}
if(f){
print(pos, pos, k+1);
printf("\n");
break;
}
}
if(f==0)printf("no arbitrage sequence exists\n");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: