题意:N点M边的无向图,边上有线性不下降的温度,给固定入口S,有E个出口。逃出去,使最大承受温度最小。输出该温度,若该温度超过H,输出-1。

 

羞涩的题意

显然N*H的复杂度dp[n][h]表示到达n最大温度为h的最小时间(由于温度不下降,这样不会更差,故可以这么搞)

一开始读错题了,以为是温度累加什么鬼...

然后分别写了2种方法,二分和不二分的

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <vector>
  7 #include <string>
  8 #include <set>
  9 #include <queue>
 10 using namespace std;
 11 
 12 #define ll long long
 13 #define MP make_pair
 14 
 15 #define inf 0x3f3f3f3f
 16 #define eps 1e-8
 17 
 18 #define maxn 110
 19 struct edge{
 20     int v,nxt;
 21     int w,r,p;
 22 }e[maxn*maxn*2];
 23 int head[maxn], sz;
 24 void init(){sz=0;memset(head,-1,sizeof(head));}
 25 void addedge(int u,int v,int w,int ri,int pi){
 26     e[sz].v=v,e[sz].nxt=head[u];
 27     e[sz].w=w,e[sz].r=ri,e[sz].p=pi;
 28     head[u]=sz++;
 29 }
 30 int dp[maxn][10010];
 31 bool ed[maxn];
 32 bool ins[maxn][10010];
 33 int pre[maxn][10010][2];
 34 int getout;
 35 void dfs(int u,int hp,int S,int cnt){
 36     if(u==S){printf("%d %d",cnt+1,u);return ;}
 37     dfs(pre[u][hp][0],pre[u][hp][1],S,cnt+1);
 38     printf(" %d",u);
 39 }
 40 bool check(int mahp, int S){
 41     memset(dp,0x3f,sizeof(dp));
 42     dp[S][0] = 0;
 43     memset(ins,false,sizeof(ins));
 44     ins[S][0] = true;
 45     queue<pair<int,int> >que;
 46     que.push(MP(S,0));
 47     if(ed[S]){getout = S;return true;}
 48     while(!que.empty()){
 49         int u = que.front().first;
 50         int hp = que.front().second;
 51         int t = dp[u][hp];
 52         que.pop();
 53         ins[u][hp] = false;
 54         for(int i=head[u];i!=-1;i=e[i].nxt){
 55             int v = e[i].v;
 56             int w = e[i].w;
 57             int r = e[i].r;
 58             int p = e[i].p;
 59             ll tmp = r+p*(t+w);
 60             if(tmp>mahp) continue;
 61             int hp2 = max(hp,int(tmp));
 62             if(dp[v][hp2]>dp[u][hp]+w){
 63                 pre[v][hp2][0] = u;
 64                 pre[v][hp2][1] = hp;
 65                 if(ed[v]){getout = v;return true;}
 66                 dp[v][hp2] = dp[u][hp]+w;
 67                 if(ins[v][hp2]==false){
 68                     ins[v][hp2] = true;
 69                     que.push(MP(v,hp2));
 70                 }
 71             }
 72         }
 73     }
 74     return false;
 75 }
 76 int main(){
 77     int n,m,H,S,E;
 78     while(~scanf("%d%d%d%d%d",&n,&m,&H,&S,&E)){
 79         memset(ed,false,sizeof(ed));
 80         init();
 81         for(int i=0;i<m;++i){
 82             int u,v,w,r,p;
 83             scanf("%d%d%d%d%d",&u,&v,&w,&r,&p);
 84             addedge(u,v,w,r,p);
 85             addedge(v,u,w,r,p);
 86         }
 87         for(int i=0;i<E;++i){
 88             int tmp;
 89             scanf("%d",&tmp);
 90             ed[tmp] = true;
 91         }
 92         int l=0,r=H+1;
 93         while(l<r){
 94             int mid = (l+r)/2;
 95             if(check(mid,S)) r = mid;
 96             else l = mid+1;
 97         }
 98         if(r<=H){
 99             puts("YES");
100             printf("%d\n",r);
101             check(r,S);
102             dfs(getout,r,S,0);
103             puts("");
104         }else puts("NO");
105     }
106     return 0;
107 }
二分代码

相关文章: