zoukankan      html  css  js  c++  java
  • POJ3635 Full Tank? 变形最短路

      题目链接:http://poj.org/problem?id=3635

      容易想到用二维数组记录状态求最短路,然后用优先队列优化,类似于Dijkstra和BFS。我开始设计的过程是直接直接从当前点向相邻点转移并找出所有可能状态,结果TLE。貌似是无关状态太多了,没想到卡得这么紧。别人的做法是只考虑两个状态:1、加一单位油 2、向相邻点移动;这样就砍掉了一些对最优解不必要的状态。

     1 //STATUS:C++_AC_297MS_2404KB
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<queue>
    11 #include<stack>
    12 using namespace std;
    13 #define LL __int64
    14 #define pdi pair<double,int>
    15 #define Max(a,b) ((a)>(b)?(a):(b))
    16 #define Min(a,b) ((a)<(b)?(a):(b))
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define lson l,mid,rt<<1
    19 #define rson mid+1,r,rt<<1|1
    20 const int N=1010,M=1000000,INF=0x3f3f3f3f,MOD=1999997;
    21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL;
    22 const double DNF=100000000;
    23 
    24 struct Node{
    25     int d,u,c;
    26     bool operator < (const Node &ths) const {
    27         return d>ths.d;
    28     }
    29 };
    30 struct Edge{
    31     int u,v,w;
    32 }e[N*20];
    33 int vis[N][110],d[N][110],w[N],first[N],next[N*20];
    34 int n,m,t,mt,cup;
    35 
    36 void adde(int a,int b,int c)
    37 {
    38     e[mt].u=a,e[mt].v=b,e[mt].w=c;
    39     next[mt]=first[a],first[a]=mt++;
    40     e[mt].u=b,e[mt].v=a,e[mt].w=c;
    41     next[mt]=first[b],first[b]=mt++;
    42 }
    43 
    44 int Dijkstra(int s,int end)
    45 {
    46     int i,j,k,dis,u,v,c;
    47     Node t;
    48     priority_queue<Node> q;
    49     mem(vis,0);
    50     mem(d,INF);
    51     d[s][0]=0;
    52     q.push(Node{0,s,0});
    53     while(!q.empty()){
    54         t=q.top();q.pop();
    55         u=t.u;c=t.c;
    56         if(u==end)return t.d;
    57         if(vis[u][c])continue;
    58         vis[u][c]=1;
    59         if(c<cup && t.d+w[u]<d[u][c+1]){
    60             d[u][c+1]=t.d+w[u];
    61             q.push(Node{d[u][c+1],u,c+1});
    62         }
    63         for(i=first[u];i!=-1;i=next[i]){
    64             v=e[i].v;
    65             if(c>=e[i].w && d[u][c]<d[v][c-e[i].w]){
    66                 d[v][c-e[i].w]=d[u][c];
    67                 q.push(Node{d[u][c],v,c-e[i].w});
    68             }
    69         }
    70     }
    71     return -1;
    72 }
    73 
    74 int main()
    75 {
    76  //   freopen("in.txt","r",stdin);
    77     int i,j,a,b,c,ans;
    78     while(~scanf("%d%d",&n,&m))
    79     {
    80         mt=0;
    81         mem(first,-1);
    82         for(i=0;i<n;i++)
    83             scanf("%d",&w[i]);
    84         for(i=0;i<m;i++){
    85             scanf("%d%d%d",&a,&b,&c);
    86             adde(a,b,c);
    87         }
    88         scanf("%d",&t);
    89         while(t--){
    90             scanf("%d%d%d",&cup,&a,&b);
    91             ans=Dijkstra(a,b);
    92             if(ans!=-1)printf("%d\n",ans);
    93             else printf("impossible\n");
    94         }
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    FZU 2098 刻苦的小芳(卡特兰数,动态规划)
    卡特兰数总结
    FZU 1064 教授的测试(卡特兰数,递归)
    HDU 4745 Two Rabbits(区间DP,最长非连续回文子串)
    Java 第十一届 蓝桥杯 省模拟赛 正整数的摆动序列
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密
    Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密
  • 原文地址:https://www.cnblogs.com/zhsl/p/2883859.html
Copyright © 2011-2022 走看看