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 }

 

posted @ 2012-05-08 21:12  知行执行  阅读(196)  评论(0编辑  收藏  举报