zoukankan      html  css  js  c++  java
  • HDU

    一个图上,有M条边,Z个出发点,Y个终止点。求一条最短路,其中起点是Z中的任意一点,终点是Y中任意一点。

    Input

    输入数据有多组,输入直到文件结束。

    每组的第一行是三个整数M,Z,Y

    接着有M行,每行有三个整数a,b,w,表示a,b之间存在一条长度为w的边 (1=<(a,b)<=1000,w原题干未给范围c++ int够用),可能存在重边,边为双向边。

    接着的第M+1行有Z个数,表示起点标号

    接着的第M+2行有Y个数,表示终点标号

    Output

    每组数据,输出一个整数占一行表示最短路的长度

    Sample Input

    6 2 3
    1 3 5
    1 4 7
    2 8 12
    3 8 4
    4 9 12
    9 10 2
    1 2
    8 9 10

    Sample Output

    9

    代码(邻接矩阵):

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<vector>
      7 using namespace std;
      8 const int maxn=1005;
      9 typedef long long ll;
     10 #define INF 0x3f3f3f3f
     11 struct shudui1
     12 {
     13     ll start,value;
     14     bool operator < (const shudui1 q)const
     15     {
     16         return value<q.value;
     17     }
     18 } str1;
     19 struct shudui2
     20 {
     21     ll start,value;
     22 } str2;
     23 ll v1[maxn],v2[maxn],v[maxn],k[maxn][maxn];
     24 priority_queue<shudui1>r;
     25 void JK(ll maxx)
     26 {
     27     memset(v,INF,sizeof(v));
     28     v[0]=0;
     29     str1.start=0;
     30     str1.value=0;
     31     r.push(str1);
     32     while(!r.empty())
     33     {
     34         ll x,y;
     35         str1=r.top();
     36         r.pop();
     37         x=str1.start;
     38         y=str1.value;
     39         if(v[x]<y) continue;
     40         //说明在这个点再此之后又入队了
     41         //此次出队的并不是s到这个点的最短路,
     42         //所以在这次更新前点v所连的点已经更过一次了
     43         //所以后面也不会进行松弛操作
     44         for(ll i=0; i<=maxx; ++i)
     45         {
     46             if((v[x]+k[x][i]<v[i]))
     47             {
     48                 v[i]=v[x]+k[x][i];
     49                 str1.start=i;
     50                 str1.value=v[i];
     51                 r.push(str1);
     52             }
     53         }
     54     }
     55 }
     56 
     57 int main()
     58 
     59 {
     60 
     61     ll n,m,p,a,b,c;
     62 
     63     while(scanf("%lld %lld %lld",&n,&m,&p)!=EOF)
     64 
     65     {
     66 
     67         memset(k,INF,sizeof(k));
     68 
     69         ll maxx=n;
     70 
     71         for(ll i=1; i<=n; i++)
     72 
     73         {
     74 
     75             scanf("%lld %lld %lld",&a,&b,&c);
     76 
     77             maxx=max(maxx,max(a,b));  //记录顶点上限
     78 
     79             k[a][b]=min(c,k[a][b]);  //保存最小边权
     80 
     81             k[b][a]=min(c,k[a][b]);
     82 
     83         }
     84 
     85         for(ll i=0; i<m; i++)
     86 
     87         {
     88 
     89             scanf("%lld",&a);
     90 
     91             k[a][0]=k[0][a]=0;
     92 
     93         }
     94 
     95         for(ll i=0; i<p; i++)
     96 
     97             scanf("%lld",&v2[i]);
     98 
     99         ll minn=INF;
    100 
    101         JK(maxx);
    102 
    103         for(ll j=0; j<p; j++)  //找到最小路径
    104 
    105             if(v[v2[j]]<minn)
    106 
    107                 minn=v[v2[j]];
    108 
    109         printf("%lld
    ",minn);
    110 
    111     }
    112 
    113 }
    View Code

    代码(邻接表)+注释:

      1 /*
      2 这道题首先不能暴力枚举起点和终点,所以floyd就不用再用了
      3 
      4 我们只需要弄一个新节点(我代码中是maxx),让起点和新节点连一条边,边的距离为0,这样的话只需要跑一边迪杰斯特拉算法后,在v数组中枚举终点,取最小值就可以了
      5 
      6 错了这么多次,才发现原来我是没有清空vector容器。。。
      7 用邻接表存图是不用考虑有重边这个问题的
      8 
      9 */
     10 #include<stdio.h>
     11 #include<string.h>
     12 #include<iostream>
     13 #include<algorithm>
     14 #include<queue>
     15 #include<vector>
     16 using namespace std;
     17 const int maxn=1005;
     18 typedef long long ll;
     19 #define INF 0x3f3f3f3f
     20 struct shudui1
     21 {
     22     ll start,value;
     23     bool operator < (const shudui1 q)const
     24     {
     25         return value<q.value;
     26     }
     27 } str1;
     28 struct shudui2
     29 {
     30     ll start,value;
     31 } str2;
     32 ll v1[maxn],v2[maxn],v[maxn];
     33 priority_queue<shudui1>r;
     34 vector <shudui2>w[2005];
     35 void JK(ll s)
     36 {
     37     memset(v,INF,sizeof(v));
     38     v[s]=0;
     39     str1.start=s;
     40     str1.value=0;
     41     r.push(str1);
     42     while(!r.empty())
     43     {
     44         ll x,y;
     45         str1=r.top();
     46         r.pop();
     47         x=str1.start;
     48         y=str1.value;
     49         if(v[x]<y) continue;
     50         //说明在这个点再此之后又入队了
     51         //此次出队的并不是s到这个点的最短路,
     52         //所以在这次更新前点v所连的点已经更过一次了
     53         //所以后面也不会进行松弛操作
     54         ll len=w[x].size();
     55         for(ll i=0; i<len; ++i)
     56         {
     57             str2=w[x][i];
     58             if((v[x]+str2.value<v[str2.start]))
     59             {
     60                 v[str2.start]=v[x]+str2.value;
     61                 str1.start=str2.start;
     62                 str1.value=v[str2.start];
     63                 r.push(str1);
     64             }
     65         }
     66     }
     67 }
     68 int main()
     69 {
     70     ll a,z,y,d,f,g;
     71     while(~scanf("%lld%lld%lld",&a,&z,&y))
     72     {
     73         ll maxx=0;
     74         while(a--)
     75         {
     76             scanf("%lld%lld%lld",&d,&f,&g);
     77             maxx=max(maxx,max(d,f));
     78             str2.start=f;
     79             str2.value=g;
     80             w[d].push_back(str2);
     81             str2.start=d;
     82             str2.value=g;
     83             w[f].push_back(str2);
     84         }
     85         maxx+=1;
     86         for(ll i=1; i<=z; ++i)
     87         {
     88             scanf("%lld",&v1[i]);
     89             str2.start=v1[i];
     90             str2.value=0;
     91             w[maxx].push_back(str2);
     92             str2.start=maxx;
     93             str2.value=0;
     94             w[v1[i]].push_back(str2);
     95         }
     96 
     97         for(ll i=1; i<=y; ++i)
     98             scanf("%lld",&v2[i]);
     99         ll minn=INF;
    100 
    101         JK(maxx);
    102         for(ll j=1; j<=y; ++j)
    103         {
    104             minn=min(minn,v[v2[j]]);
    105         }
    106 
    107         printf("%lld
    ",minn);
    108         for(int i=1;i<=maxx;++i)
    109         {
    110             w[i].clear();
    111         }
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    团队冲刺4
    团队冲刺3
    团队冲刺2
    团队冲刺1
    01大道至简阅读笔记
    03 梦断代码阅读笔记
    TOMCAT------>web资源访问
    Tomcat----->tomcat配置虚拟主机(搭建网站)mac
    Linux中常用操作命令
    tomcat------->简单配置
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12617851.html
Copyright © 2011-2022 走看看