ZJUT1566打酱油Dijkstra

    技术2022-05-20  31

    Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1566

     

    一道Dijkstra的算法题。

     

    第一次看了一遍觉得可以用Dijkstra,刚好快看到那里,所以之后花了点时间看了那个算法。

     

    后来又看到,于是开始写。但是写着写着发现不行。因为还要求返回的路程。

     

    于是又搁下。

     

    今天再看到,发现只要求两次就可以实现。

     

    思路:进行一次Dijkstra,算出开始结点到每个点的最短路径。然后把所有边反向,重新(还是从开始结点)计算一次Dijkstra,就可以求出任何一个结点到达开始结点的最短路径。只要把打酱油的地点的对应的两个路径相加,选出最小值即可。

     

    这是第一次写Dijkstra,所以可能写的有点粗糙。而且还不会用优先队列,所以时间得不到好的优化。

     

     

    以下贴代码:

     

    #include <iostream>using namespace std;const int MAX = 100000;int map1[1005][1005],map2[1005][1005];int d1[1005],d2[1005];int shop[1005];bool visited[1005];int n,e,k;int min(int a, int b){ if (a<=b) return a; else return b;}void dijkstra(int v, int map[1005][1005], int d[1005]){ int i,ct,temp,temppoint; for (i=1; i<=n; i++) {  visited[i] = false; } d[v] = 0; ct = n; while(ct) {    temp = MAX;  for (i=1; i<=n; i++)  {   if (!visited[i])   {    if (temp>d[i])    {     temp = d[i];     temppoint = i;    }   }  }  visited[temppoint] = true;  ct--;  for (i=1; i<=n; i++)  {   if (map[temppoint][i]<MAX)   {    d[i] = min(d[temppoint]+map[temppoint][i],d[i]);   }  } }}int main(){ int i,j,a,b,val,len; while(scanf("%d %d %d", &n, &e, &k)!=EOF) {  for (i=1; i<=n; i++)  {   for (j=1; j<=n; j++)   {    map1[i][j] = MAX;    map2[i][j] = MAX;   }  }  for (i=0; i<e; i++)  {   scanf("%d %d %d", &a, &b, &val);   if (val<map1[a][b])   {    map1[a][b] = val;    map2[b][a] = val;   }  }  for (i=1; i<=n; i++)  {   d1[i] = MAX;   d2[i] = MAX;  }  for (i=0; i<k; i++)  {   scanf("%d", &shop[i]);  }  dijkstra(1, map1, d1);  dijkstra(1, map2, d2);  len = MAX;  for (i=0; i<k; i++)  {   len = min(len, d1[shop[i]]+d2[shop[i]]);  }  printf("%d/n", len); } return 0;}


    最新回复(0)