NYOJ 307

View Code
  1 /*

  2 题外话:

  3 没想到这是一道最短路题

  4 原来最短路可以这样变形,有时也可以多次利用最短路

  5 求一个问题

  6 思路:

  7 我们从每个有藏宝的地方为起点 求到各个点的可以的最大

  8 重量

  9 

 10 我们相当于求出了从出口 到 一个藏宝点 所

 11 允许的最大重量

 12 

 13 把所有藏宝点的按重量 排序(从小到大)

 14 先到最小的藏宝点带上 宝物 再去次大

 15 一次类推 

 16 */

 17 #include<iostream>

 18 #include<cstdio>

 19 #include<cstring>

 20 #include<algorithm>

 21 using namespace std;

 22 

 23 const int size = 8001;

 24 struct node

 25 {

 26    int e;

 27    int v;

 28    int next;

 29 }edge[30001];

 30 int k[size];

 31 int en=0;

 32 

 33 int qmin(int x,int y)

 34 {

 35   if(x<y)return x;

 36   else return y;

 37 }

 38 

 39 int dij(int beg,int last,int N)

 40 {

 41    int i;

 42    bool flag[size];

 43    int d[size];

 44    memset(flag,0,sizeof(flag));

 45    memset(d,0,sizeof(d));

 46    d[beg]=7777777;

 47    flag[beg]=1;

 48    while(beg!=last)

 49     {

 50       for(i=k[beg];i!=-1;i=edge[i].next)

 51         {

 52            int e = edge[i].e;

 53            int v = edge[i].v;

 54            if(!flag[e] && d[e]<qmin(d[beg],v))

 55             d[e]=qmin(d[beg],v);

 56         }

 57       int tmax=0;

 58       for(i=1;i<=N;++i)

 59        if(!flag[i]&&d[i]>tmax)

 60         {

 61           tmax=d[i];

 62           beg=i;

 63         }

 64       flag[beg]=1;

 65     }

 66    return d[last];

 67 }

 68 

 69 int main()

 70 {

 71   int N,M,K,W,i;

 72   int x,y,z;

 73   int kc[size];

 74   int d[size];

 75   while(~scanf("%d%d%d%d",&N,&M,&K,&W))

 76    {

 77      memset(k,-1,sizeof(k));

 78      en=0;

 79      for(i=1;i<=K;++i)

 80       scanf("%d",&kc[i]);

 81      for(i=0;i<M;++i)

 82       {

 83         scanf("%d%d%d",&x,&y,&z);

 84         

 85         edge[en].e=y;

 86         edge[en].v=z;

 87         edge[en].next=k[x];

 88         k[x]=en++;

 89         

 90         edge[en].e=x;

 91         edge[en].v=z;

 92         edge[en].next=k[y];

 93         k[y]=en++;

 94       }

 95      for(i=1;i<=K;++i)

 96       d[i]=dij(kc[i],1,N);

 97      sort(d+1,d+K+1);

 98      int total=0;

 99      for(i=1;i<=K;++i)

100        if(d[i]>=(total+1)*W)

101         total++;

102      printf("%d\n",total);

103    }

104   return 0;

105 }

 

你可能感兴趣的:(OJ)