POJ 1860Currency Exchange

    技术2022-05-19  19

    题目大意:给定n种货币及其汇率,求能否通过货币兑换使得你手里的钱币增多、细想一下其实就是求一条最长路,那关键问题就是如何判断循环终止了。

    我想主要有下面两个边界条件:

          1.当不能松弛的时候停止, 这样就代表这个图中没有正环,这样判断一下dist[xx]是否大于curmoney就可以了。

          2.管他妈什么正环负环,把起点到所有点的距离更新一遍看看dist[start]是否大于curmoney就行了。

    这题我wa了估计有10多次,一开始用的是邻接表……后来想想还有上税的操作,自己的邻接表模版不大方便,就上网找了一份邻接矩阵的代码,改了n次还是wa,再看discuss的时候发现还有精度的问题,(以后注意:凡是涉及到double运算复杂的问题有时候都要判断精度的问题,不然容易超时!)要熟练掌握邻接矩阵和邻接表两种形式的运算!

    下面的代码中有一开始写邻接表的部分代码,希望日后完成邻接表的代码!

     

    #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define init(a,what) memset(a,what,sizeof(a)) #define read freopen("zx.in","r",stdin) #define write freopen("zx.out","w",stdout) #define INF 0x3f3f3f3f #define eps 1e-8 const int MAXN=100+10; //const int MAXM=1000+10; queue<int>q; int kmoney,mnum,haven,ans,a,b,circle[MAXN];//u[MAXM],v[MAXM],next[MAXN],first[MAXN]; double curmoney,dist[MAXN],r[MAXN][MAXN],c[MAXN][MAXN];//rab,cab,rba,cba,w[MAXN],m[MAXN] bool vis[MAXN]; /*void read_G(int a,int b,double cminte,double cexcept) { ans++; u[ans]=a, v[ans]=b, w[ans]=cminte, m[ans]=cexcept; next[ans]=first[u[ans]]; first[u[ans]]=ans; }*/ bool spfa(int start) { init(vis,false); init(circle,0); for(int i=1;i<=kmoney;i++) dist[i]=(i==start ? curmoney : 0); q.push(start); circle[start]++; while(!q.empty()) { int xx=q.front(); q.pop(); vis[xx]=false; for(int i=1;i<=kmoney;i++) { if(r[xx][i]>eps && (dist[i]+eps)<(dist[xx]-c[xx][i])*r[xx][i]) { dist[i]=(dist[xx]-c[xx][i])*r[xx][i]; if(!vis[i]) { vis[i]=true; q.push(i); } if(++circle[i]>kmoney) return true;//优化! } } /*for(int e=first[xx];e!=-1;e=next[e]) { if(dist[v[e]]<(dist[xx]-m[xx])*w[e]) { dist[v[e]]=(dist[xx]-m[xx])*w[e]; if(!vis[v[e]]) { vis[v[e]]=true; q.push(v[e]); } } }*/ } return dist[start]>curmoney+eps; } int main() { //read, write; while(scanf("%d%d%d%lf",&kmoney,&mnum,&haven,&curmoney)!=EOF) { for(int i=1;i<=mnum;i++) { //ans=0; scanf("%d%d",&a,&b); scanf("%lf%lf%lf%lf",&r[a][b],&c[a][b],&r[b][a],&c[b][a]); //scanf("%d%d%lf%lf%lf%lf",&a,&b,&rab,cab,&rba,&cba); //read_G(a,b,rab,cab); //read_G(b,a,rba,cba); } if(spfa(haven)) printf("YES/n"); else printf("NO/n"); } return 0; }


    最新回复(0)