1. Dijkstra算法
   这个算法和prime求最小生成树特别像,都是找到最小边,把点加进来,然后用新加的点更新其他没有被加进来的点。
   1.
      
#define N 1002
   
2.
      
#define MAX 99999
   
3.
      
int edges[N][N],d[N],n;
   
4.
       
   
5.
      
void dijkstra(int v)
   
6.
      {
   
7.
              
int i,j;
   
8.
              
bool s[N]={false};
   
9.
              
for(i=1;i<=n;i++)
  
10.
                      d[i]
=edges[v][i];
  
11.
              d[v]
=0;s[v]=true;
  
12.
              
for(i=1;i<n;i++)
  
13.
              {
  
14.
                      
int temp=MAX;
  
15.
                      
int u=v;
  
16.
                      
for(j=1;j<=n;j++)
  
17.
                              
if((!s[j])&&(d[j]<temp))
  
18.
                              {
  
19.
                                      u
=j;
  
20.
                                      temp
=d[j];
  
21.
                              }
  
22.
                              s[u]
=true;
  
23.
                              
for(j=1;j<=n;j++)
  
24.
                                      
if((!s[j])&&(edges[u][j]<MAX)&&(d[u]+edges[u][j])<d[j])
  
25.
                                              d[j]
=d[u]+edges[u][j];
  
26.
              }
  
27.
       
  
28.
      }

2. SPFA算法 (shortest path faster algorithm)
    不断维护一个队列,如果队列里的点,使得其他点的最短路得到松弛,则这个点还有可能使另外的点松弛,所以如果这个点不在队列里,就把它入队。
    很多时候,给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。 此算法时间复杂度为O(2*E),E为边数。
 //pku1860 
    #include<stdio.h>
    #include
<string.h>
    #include
<vector>
    
#define N 120
    
using namespace std;
    
struct Point
    {
        
int id;
        
double r, c;
    };
    vector
<Point> p[N];
    
int q[N],n,m,S,visit[N];
    
double V,dist[N];
    
int spfa()
    {
        memset(visit, 
0sizeof(visit));
        
int i,j,head=0,tail=1,x;
        
for(i=1; i<=n ;i++)
            dist[i]
=0;    //此题是求换得的货币最多,所以初值赋0;
                          
//若求最短路,初值应赋为无穷大
        if(V<=0return 0;
        q[
0]=S;
        dist[S]
=V;        //S为源,若求最短路,则dist[S]=0;
        visit[S]=1;
        
while(head!=tail){ // Attention!!!由于对队列长度取模了,所以head<tail不一定成立,应改为head!=tail
            x=q[head];
            visit[x]
=0;
            head
=(head+1)%N;
            
for(i=0; i<p[x].size(); i++){

                j
=p[x][i].id;
                
if(dist[j]<(dist[x]-p[x][i].c)*p[x][i].r){
                    dist[j]
=(dist[x]-p[x][i].c)*p[x][i].r;
                    
if(!visit[j]){
                        q[tail]
=j;
                        tail
=(tail+1)%N;
                        visit[j]
=1//若如果j点的最短路径估计值有所调整,
                                    
// 且j点不在当前的队列中,就将j点放入队尾
                    }
                }
            }
            
if(dist[S]>V) return 1;
        }
        
return 0;
    }
    
int main()
    {
        
int i,j,a,b;
        
double rab, cab, rba, cba;
        Point p1, p2;
        
while(scanf("%d %d %d %lf",&n, &m, &S, &V)!=EOF){
            
for(i=1; i<=n; i++)
                p[i].clear();
        
for(i=0; i<m; i++){
            scanf(
"%d %d %lf %lf %lf %lf",&a, &b, &rab, &cab, &rba, &cba);
            p1.id
=b; p1.r=rab; p1.c=cab;
            p2.id
=a; p2.r=rba; p2.c=cba;
            p[a].push_back(p1);
            p[b].push_back(p2);
        }
        j
=spfa();
        
if(j)
            printf(
"YES\n");
        
else
            printf(
"NO\n");
        }
        
return 0;
    }