CF-95C-建图+最短路

http://codeforces.com/problemset/problem/95/C

  n点m边(无向有权),每个点有一个司机(Ti,Ci)表示支付Ci元走Ti长度且必须停在节点才合法,一个司机只能使用最多一次,问从x-y最小花费。

  n,m<=1000,预处理处任意两点最短距离,然后按照Ci建立新图,如果i点司机的Ti足够到达j那么就连边,最后在新图跑最短路。

  

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define mp make_pair
 5 #define pb push_back
 6 #define fi first
 7 #define se second
 8 #define pii pair<int,int>
 9 #define inf 0x3f3f3f3f3f3f3f3f
10 const int maxn=1010;
11 vector<pii>g1[maxn],g2[maxn];
12 LL d[maxn];
13 int T[maxn],C[maxn];
14 int n,m,x,y;
15 bool vis[maxn];
16 void spfa(int st,LL d[],vector<pii> g[]){
17     memset(vis,0,sizeof(vis));
18     memset(d,inf,sizeof(LL)*(n+1));
19     queue<int>q;
20     q.push(st);
21     vis[st]=1,d[st]=0;
22     while(!q.empty()){
23         int u=q.front();q.pop();vis[u]=0;
24         for(auto e:g[u]){
25             int v=e.fi,w=e.se;
26             if(d[v]>d[u]+w){
27                 d[v]=d[u]+w;
28                 if(!vis[v])q.push(v),vis[v]=1;
29             }
30         }
31     }
32 }
33 
34 int main(){
35     int u,v,w;
36     cin>>n>>m>>x>>y;
37     while(m--){
38         cin>>u>>v>>w;
39         g1[u].push_back(mp(v,w));
40         g1[v].push_back(mp(u,w));
41     }
42     for(int i=1;i<=n;++i)cin>>T[i]>>C[i];
43     for(int i=1;i<=n;++i){
44         spfa(i,d,g1);
45         for(int j=1;j<=n;++j){
46             if(i==j || d[j]>T[i])continue;
47             g2[i].pb(mp(j,C[i]));
48         }
49     }
50     spfa(x,d,g2);
51     if(d[y]==inf)cout<<-1;
52     else cout<<d[y]<<'\n';
53     return 0;
54 }

 

posted @ 2019-04-16 14:20  *zzq  阅读(318)  评论(0编辑  收藏  举报