最短路 dijkstra---poj3268

2016-5-9 回顾: dijkstra = dp+贪心

这个算法实际上不就是,先找一个源点,然后把其他所有点的距离记录下来,遍历一遍所有的边,每一条边我们可以选择更新某一个点(端点)到源点的距离,再拿这个点的的边去松弛别的点(Ps:我也不知道自己是不是在乱J8想,个人感觉这个和dp里面的 更新操作 有一点相似之处,和贪心也有关系,其实都运用到了这几种想法)

先介绍一下刘汝佳书上的算法:
不要用来当模板,应该有很多数据结构在书上,并没有写下来,只是汲取一下其中思想

void dijkstra(int s){
   priority_queue<HeapNode> Q;   //优先队列,距源点小的点放前面
   for(int i=0;i<n;i++) d[i]=inf;   
   d[s]=0;                    
   memset(done,0,sizeof(done));  //如果对这个点访问过,done设为1
   Q.push((HeadNode){0,s});        
   while(!Q.empty()){
      HeadNode x=Q.top(); Q.pop();    
      int u=x.u;             //u是点的编号
      if(done[u]) continue; 
      done[u]=true;        
      for(int i=0;i<G[u].size();i++){
         Edge& e=edges[G[u][i]];      //G[u] 表示从u出发的所有边 ,G[u][i] 表示从u出发第i短 //的边,前面有放入的规则
         if(d[e.to]>d[u]+e.dist){
           d[e.to]=d[u]+e.dist;        
           p[e.to]=G[u][i];              //p[e.to] 代表 e.to的编号
         }
      }
   }
}

这个算法的时间复杂度是mlogn ,m代表边数。
这个算法的核心就是优先队列,把d小的点放到前面,做过的点不再进行操作。每次提取的点都是离源点最近的点,以此可以保证d[i]都是最短路径;

poj–3268
题意:http://vj.acmclub.cn/problem/viewProblem.action?id=47402
有N 头牛 在N个农场 将要去X农场举办party, 有M 条路连接这N个农场(或者
N,M,X;
然后M行 每行:from to 和 time;

省略头文件:
using namespace std;
#define MAX_V 8000
#define INF 0x7fffffff //INT_MAX
#define inf 0x3f3f3f3f

// 从顶点from指向顶点to的权值为cost的边
struct edge
{
    int to, cost;
    edge(){}
    edge(int to, int cost) : to(to), cost(cost){}
};

// first 最短路径,second顶点编号
typedef pair<int, int> P;
int flag[MAX_V];

vector<edge>  G[MAX_V];          // 图

void intG(){                     //初始化图G 很多题目是需要你初始化的图的。
    for(int i=1;i<=100;i++)
        for(int j=0;j<G[i].size();j++)
            G[i][j].cost=inf;
}
// 最短距离
int d[MAX_V][MAX_V];   //这里有个不同点,用d[i][j]表示i,j之间的距离
int V, E;              // V是顶点数,E是边数

// 求解从顶点s出发到所有点的最短距离
void dijkstra(int s)
{
    mem(flag);
    priority_queue<P, vector<P>, greater<P> > que;
    memset(d[s], inf,  sizeof(d[s])); 
    d[s][s] = 0;             //到本身为0;
    que.push(P(0, s));

    while (!que.empty())
    {
        P p = que.top(); que.pop();
        int v = p.second;         
        if (flag[v]) continue;             //做过就跳过
        flag[v]=1;                          
        for (int i = 0; i < G[v].size(); ++i)
        {
            edge e = G[v][i];
            if (d[s][e.to] > d[s][v] + e.cost)
            {
                d[s][e.to] = d[s][v] + e.cost;
                que.push(P(d[s][e.to], e.to));
            }
        }
    }
}

///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{

    freopen("1.txt", "r", stdin);
     int t;
     int N,M,X;
     while (~scanf("%d %d %d", &N,&M,&X)){
              intG();
            for(int i=0;i<M;i++){
                int a,b,t;
                scanf("%d %d %d",&a,&b,&t);
                G[a].push_back(edge(b,t));            //存储数据
              // G[b].push_back(edge(a,t)); 如果是无向图,记得加这个
            } 
            for(int i=1;i<=N;i++)
                  dijkstra(i);
            int ans=-1;
            for(int i=1;i<=N;i++)
                ans=max(ans,d[i][X]+d[X][i]);
            printf("%d\n",ans);
        }
        return 0;
    }

你可能感兴趣的:(dijkstra)