POJ 2240 Arbitrage 解题报告

24 篇文章 0 订阅
11 篇文章 0 订阅

Question Link

单向图,就是bellman-ford求正环,但是应该预设起点的钱的值为1,或者任意正数。起点暴力,枚举。好吧(其实我是真的傻了)。

傻傻的代码

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val)	 memset(var,val,sizeof(var))
#define LL long long 
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
#define lowbit(x)   x&(-x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define M 1090
#define N 390
map<string,int >mapp;  
int n,m,etot,Case; 
struct node {
	int u,v; double w; 
}e[M];
inline void addead(int u,int v,double w){
	++etot;
	e[etot].u = u; 	e[etot].v = v; 	e[etot].w = w; 
}
void init(){
	etot = 0; 
	mapp.clear();
}
double dis[N];
bool bellman(){
	for (int ai = 1; ai <= n; ai++){
		mset(dis,0);
		dis[ ai ] = 1; 
		
		for (int ci = 1; ci <= n-1; ci++){
			for (int di = 1; di <= etot; di++){
				if ( dis[ e[di].v ] < dis[ e[di].u ] * e[ di ].w ){
					dis[ e[di].v ] = dis[ e[di].u ] * e[ di ].w;
				}
			}			
		}
		for (int di = 1; di <= etot; di++){
			if ( dis[ e[di].v ] < dis[ e[di].u ]*e[di].w )
				return true; 
		}
		
	}
	return false;
}
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	Case = 0; 
	while ( scanf("%d",&n) != EOF && n ){
		init();
		rep(i,1,n){
			string a;	cin>>a; 
			mapp[ a ] = i; 			
		}
		scanf("%d",&m);
		rep(i,1,m){
			string a,b; double ww; 
			cin>>a>>ww>>b; 
			addead(mapp[a],mapp[b],ww);
		}
		if ( bellman( ) ){
			printf("Case %d: Yes\n",++Case);
		}
		else 
			printf("Case %d: No\n",++Case);
	}
	return 0;
}

但是似乎不影响复杂度和结果。因为会return出去。
但还是体现我的对Bellman_Ford 检测负环回路的不理解。

改正的代码

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val)	 memset(var,val,sizeof(var))
#define LL long long 
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
#define lowbit(x)   x&(-x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define M 1090
#define N 390
map<string,int >mapp;  
int n,m,etot,Case; 
struct node {
	int u,v; double w; 
}e[M];
inline void addead(int u,int v,double w){
	++etot;
	e[etot].u = u; 	e[etot].v = v; 	e[etot].w = w; 
}
void init(){
	etot = 0; 
	mapp.clear();
}
double dis[N];
bool bellman(){
	mset(dis,0);
	dis[ 1 ] = 1; 
		
	for (int ci = 1; ci <= n-1; ci++){
		for (int di = 1; di <= etot; di++){
			if ( dis[ e[di].v ] < dis[ e[di].u ] * e[ di ].w ){
				dis[ e[di].v ] = dis[ e[di].u ] * e[ di ].w;
			}
		}			
	}
	for (int di = 1; di <= etot; di++){
		if ( dis[ e[di].v ] < dis[ e[di].u ]*e[di].w )
			return true; 
	}
	return false;
}
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	Case = 0; 
	while ( scanf("%d",&n) != EOF && n ){
		init();
		rep(i,1,n){
			string a;	cin>>a; 
			mapp[ a ] = i; 			
		}
		scanf("%d",&m);
		rep(i,1,m){
			string a,b; double ww; 
			cin>>a>>ww>>b; 
			addead(mapp[a],mapp[b],ww);
		}
		if ( bellman( ) ){
			printf("Case %d: Yes\n",++Case);
		}
		else 
			printf("Case %d: No\n",++Case);
	}
	return 0;
}

Ford 解法

虽然没有bellman算法优

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val)	 memset(var,val,sizeof(var))
#define LL long long 
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
#define lowbit(x)   x&(-x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define M 1090
#define N 390
map<string,int >mapp;  
int n,m,etot,Case; 
double e[N][N];
void init(){
	etot = 0; 
	mset(e,0);
	rep(i,1,n)	e[i][i] = 1; 
	mapp.clear();
}
//double dis[N];
bool ford(){
	for (int k = 1; k <= n; k++){
		for (int i = 1; i <= n; i++){
			for (int j = 1; j <= n;j++){
				if ( e[i][j] < e[i][k]*e[k][j] ){
					e[i][j] = e[i][k]*e[k][j];
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if ( e[i][i] > 1 )
			return true; 
	return false; 		
}
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	Case = 0; 
	while ( scanf("%d",&n) != EOF && n ){
		init();
		rep(i,1,n){
			string a;	cin>>a; 
			mapp[ a ] = i; 			
		}
		scanf("%d",&m);
		rep(i,1,m){
			string a,b; double ww; 
			cin>>a>>ww>>b; 
			e[mapp[a]][mapp[b]] = ww; 
		}
		if ( ford() ){
			printf("Case %d: Yes\n",++Case);
		}
		else 
			printf("Case %d: No\n",++Case);
	}
	return 0;
}

最优解法 SPFA

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val)	 memset(var,val,sizeof(var))
#define LL long long 
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
#define lowbit(x)   x&(-x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define M 1090
#define N 390
map<string,int >mapp;  
int n,m,etot,Case; 
struct node {
	int u,v,nx; double w; 
}e[M];int hea[N]; 
inline void addead(int u,int v,double w){
	++etot;
	e[etot].u = u; 	e[etot].v = v; 	e[etot].w = w; e[etot].nx = hea[u]; hea[u] = etot; 
}
void init(){
	etot = 0; 
	mapp.clear();
	mset(hea,0);
}
double dis[N];
bool SPFA(){
	mset(dis,0);

	int num[N]; mset(num,0);
	bool inq[N]; mset(inq,0);	
	queue< int  > q; 
	dis[ 1 ] = 1;inq[ 1 ] = 1 ;q.push(1);
	while ( !q.empty() ){
		int u = q.front(); q.pop() ; 
		inq[ u ] = 0; 
		for (int i = hea[u]; i ; i = e[i].nx){
			if ( dis[ e[i].v ] < dis[ e[i].u ]*e[i].w ){
				dis[ e[i].v ] = dis[ e[i].u ]*e[i].w;
				if ( !inq[ e[i].v ] ){
					q.push( e[i].v);
					inq[ e[i].v ] = 1; 
					num[ e[i].v ]++;
					if ( num[ e[i].v ] > n )
						return true; 
				}
			}
		}
	}
	return false;
}
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	Case = 0; 
	while ( scanf("%d",&n) != EOF && n ){
		init();
		rep(i,1,n){
			string a;	cin>>a; 
			mapp[ a ] = i; 			
		}
		scanf("%d",&m);
		rep(i,1,m){
			string a,b; double ww; 
			cin>>a>>ww>>b; 
			addead(mapp[a],mapp[b],ww);
		}
		if ( SPFA( ) ){
			printf("Case %d: Yes\n",++Case);
		}
		else 
			printf("Case %d: No\n",++Case);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值