最短路 dijkstra---poj3268

来源:互联网 发布:西安 java 软件公司 编辑:程序博客网 时间:2024/06/11 19:44

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;    }
0 0