poj 1860 SPFA

来源:互联网 发布:淘宝改了名称搜不到 编辑:程序博客网 时间:2024/05/22 13:55

             心累才是最可怕的,好几天没上poj,这样不行,明天开始,继续每天一题。

            如题:http://poj.org/problem?id=1860

 

 

           给出一张各种货币交换的网络,问在网络中交换原有的货币,问货币能否增值?

 

          1.当图中存在正权环时,肯定货币是可以增值的。

          2.不存在正权环时,也有可能增值,用spfa算法,松弛操作修改求大的值,如果dist[src]>v(v是原有的钱数),也是可以增值的。

          3.2条都不行,不能增值。

        

          注意是双向边,边表大小是2倍。

           用静态邻接表实现SPFA即可。

             

        

#include<iostream>
using namespace std;
#include<queue>
//#define inf 0x0fffffff
#define MAXN 105
#define MAXM 105

int head[MAXN];
int next[MAXM*2];
double dis[MAXN];
int vis[MAXN];
int cnt[MAXN];
 double v;
struct note
{
 double rate,commission;
 int u,v;
 note(){}
 note(int u,int v,double rat,double com):u(u),v(v),rate(rat),commission(com){}
}p[MAXM*2];
int e,n,m;
void addnote(int u,int v,double r,double c)
{
 p[e]=note(u,v,r,c);
 next[e]=head[u];
 head[u]=e++;

}

int spfa(int s)
{
 int i;
 for(i=1;i<=n;i++)
  dis[i]=-1;
 dis[s]=v;
 vis[s]=true;
 queue<int>que;
 que.push(s);
 cnt[s]=1;
 while(!que.empty())
 {
  int pre=que.front();
  que.pop();
  vis[pre]=false;
  double cur=dis[pre];
  for(i=head[pre];i!=-1;i=next[i])
  {
   int v=p[i].v;
   double r=p[i].rate;
   double c=p[i].commission;
   double tmp=(cur-c)*r;
   if(tmp>dis[v])
   {
    dis[v]=tmp;
    if(!vis[v])
    {
     que.push(v);
     cnt[v]++;
     vis[v]=1;
     if(cnt[v]>n)
      return true;
    }
   }
  }
  if(dis[s]>v)
   return true;
 }
 return false; 
}

int main()
{
 int s;
 
// freopen("C:\\1.txt","r",stdin);
 scanf("%d%d%d%lf",&n,&m,&s,&v);
 memset(head,-1,sizeof(head));
// memset(next,-1,sizeof(next));
 memset(vis,0,sizeof(vis));
 memset(cnt,0,sizeof(cnt));
 e=0;
 int i;
 for(i=0;i<m;i++)
 {
  int u,v;
  double r1,c1,r2,c2;
  scanf("%d%d%lf%lf%lf%lf",&u,&v,&r1,&c1,&r2,&c2);
  addnote(u,v,r1,c1);
  addnote(v,u,r2,c2);
 }
 if(spfa(s))
  printf("YES\n");
 else
  printf("NO\n");

 return 0;
}

 

 

0 0
原创粉丝点击