标签:
Description
Input
Output
Sample Input
3 2 1 20.0 1 2 1.00 1.00 1.00 1.00 2 3 1.10 1.00 1.10 1.00
Sample Output
YES
题解:如果存在一个环使得钱增多了,说明肯定可行,因为可以无限兑换,而判断环用bellman和spfa可以判断。
bellman:
#include <iostream>
#include <cstdio>
#include <cstring>
#define mem(a) memset(a,false,sizeof(a));
using namespace std;
struct Node
{
int from;
int to;
double rate;
double com;
};
Node e[220];
double d[120];
bool bellman(double v,int s,int n,int edge)
{
for(int i = 1;i <= n;i++) //对所有的货币兑换初始化为0
{
d[i] = 0;
}
d[s] = v; //d[i]表示初始时刻的s兑换的钱
bool flag;
for(int i = 1;i <= n;i++) //n个点最短路最多有n-1条
{
flag = false;
for(int j = 0;j < edge;j++)
{
if(d[e[j].to] < (d[e[j].from] - e[j].com) * e[j].rate) //找到能兑换更多的方式,可能包含回路
{
flag = true;
d[e[j].to] = (d[e[j].from] - e[j].com) * e[j].rate;
}
}
if(!flag)
{
return false;
}
if(i == n)
{
return true;
}
}
// for(int i = 0;i < edge;i++)
// {
// if(d[e[i].to] < (d[e[i].from] - e[i].com) * e[i].rate)
// {
// return true;
// }
// }
}
int main()
{
int n,m,s;
double v;
while(scanf("%d%d%d%lf",&n,&m,&s,&v) != EOF)
{
int A,B;
int k = 0;
double rab,cab,rba,cba;
for(int i = 0;i < m;i++)
{
scanf("%d%d%lf%lf%lf%lf",&A,&B,&rab,&cab,&rba,&cba);
e[k].from = A;
e[k].to = B;
e[k].rate = rab;
e[k++].com = cab;
e[k].from = B;
e[k].to = A;
e[k].rate = rba;
e[k++].com = cba;
}
if(bellman(v,s,n,k))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}SPFA:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define mem(a) memset(a,0,sizeof(a));
using namespace std;
struct Node
{
double rate;
double com;
};
bool inQueue[120]; //入队没有
int cnt[120]; //入队次数
Node map[120][120];
double d[120];
bool spfa(int n,int s,double v)
{
mem(cnt);
mem(inQueue);
for(int i = 1;i <= n;i++)
{
d[i] = 0;
}
d[s] = v;
queue<int> q;
q.push(s);
inQueue[s] = true;
cnt[s] = 1;
while(!q.empty())
{
int t = q.front();
q.pop();
inQueue[t] = false;
for(int i = 1;i <= n;i++)
{
if(map[t][i].rate != 0.0) //与出队点能够兑换
{
if(d[i] < (d[t] - map[t][i].com) * map[t][i].rate) //兑换了钱变多
{
d[i] = (d[t] - map[t][i].com) * map[t][i].rate;
if(!inQueue[i])
{
q.push(i);
inQueue[i] = true;
}
if(++cnt[i] == n) //入队次数达到了n次,说明存在环使得钱变多 (因为每次都更新)
{
return true;
}
}
}
}
}
return false;
}
int main()
{
int n,m,s;
double v;
while(scanf("%d%d%d%lf",&n,&m,&s,&v) != EOF)
{
int A,B;
int k = 0;
double rab,cab,rba,cba;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
map[i][j].rate = 0;
}
}
for(int i = 0;i < m;i++)
{
scanf("%d%d%lf%lf%lf%lf",&A,&B,&rab,&cab,&rba,&cba);
map[A][B].rate = rab;
map[A][B].com = cab;
map[B][A].rate = rba;
map[B][A].com = cba;
}
if(spfa(n,s,v))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/wang2534499/article/details/47682215