这是第一次做最短路的题
n就是钱的种类,就是点
m*2就是边
要想有提高,就是有正环
但要先交税,有可能有负边
于是就用Bellman-Ford
看了kuanbin巨巨写的,对怎么判断负环有了深刻的理解
代码如下
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105;
double d[maxn];
int D[2*maxn][2];
double C[2*maxn][2];
int tol;
bool Bellman(int s,int n,double V)
{
for(int i=1;i<=n;i++) d[i]=0;
d[s]=V;
for(int i=1;i<n;i++)//做n-1次
{
bool flag=false;//优化
for(int j=0;j<tol;j++)
{
int u=D[j][0];
int v=D[j][1];
if(d[v] < (d[u]-C[j][1])*C[j][0])//求最大
{
flag=true;
d[v]=(d[u]-C[j][1])*C[j][0];
}
}
if(!flag)return false;//没有更新,不存在正环
}
for(int i=0;i<tol;i++)
if(d[D[i][1]]<(d[D[i][0]]-C[i][1])*C[i][0])
return true;
return false;
}
int main()
{
int N,M,S;
double V ;
while(~scanf("%d%d%d%lf",&N,&M,&S,&V)){
tol=0;
while(M--){
int a,b;
double c,d,e,f;
scanf("%d%d%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f);
D[tol][0]=a;
D[tol][1]=b;
C[tol][0]=c;
C[tol][1]=d;
tol++;
D[tol][0]=b;
D[tol][1]=a;
C[tol][0]=e;
C[tol][1]=f;
tol++;
}
// printf("hello\n");
if(Bellman(S,N,V)) printf("YES\n");
else printf("NO\n");
}
return 0;
}