• SGU 145


    节点不可重复经过的K短路问题。

    思路:二分路径长度,深搜小于等于路径长度的路径数。可以利用可重复点K短路问题中的A*函数进行剪枝。

    尝试另一种解法:把可重复点K短路A*直接搬过来,堆中的每个元素额外记录之前走过的所有点。这样就可以据此防止走重复的点。最大100个点,可用两个长整形状态压缩。

    一直PE,无法验证效率。

      1 #include <map>
      2 #include <set>
      3 #include <list>
      4 #include <queue>
      5 #include <stack>
      6 #include <cmath>
      7 #include <vector>
      8 #include <cstdio>
      9 #include <string>
     10 #include <cstring>
     11 #include <cstdlib>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 typedef long long  ll;
     16 
     17 #define eps 1e-8
     18 #define inf 0x7f3f3f3f
     19 #define debug puts("BUG")
     20 #define read freopen("in.txt","r",stdin)
     21 
     22 #define N 111
     23 #define M 11111
     24 struct node
     25 {
     26     int v,w,n;
     27 }ed[M],ed2[M];
     28 int head[N],head2[N],cnt,cnt2;
     29 struct str
     30 {
     31     int v,p;
     32 }st[M*10];
     33 struct node2
     34 {
     35     int v,g,f,dx;
     36     ll m1,m2;
     37     void set(int _v,int _g,int _f,int dx,ll m1,ll m2)
     38     {
     39         this->v = _v;
     40         this->g = _g;
     41         this->f = _f;
     42         this->dx = dx;
     43         this->m1 = m1;
     44         this->m2 = m2;
     45     }
     46     bool operator < (const node2 &n) const
     47     {
     48         if (n.f == f) return n.g < g;
     49         return n.f < f;
     50     }
     51 };
     52 void sc(int s,ll &m1,ll &m2)
     53 {
     54     if (s>50) m2 |= ((s-51)<<1);
     55     else m1 |= ((s-1)<<1);
     56 }
     57 bool ck(int s,ll m1,ll m2)
     58 {
     59     if (s>50) return (m2&((s-51)<<1)) != 0;
     60     else return (m1&((s-1)<<1)) != 0;
     61 }
     62 void init()
     63 {
     64     memset(head,-1,sizeof(head));
     65     memset(head2,-1,sizeof(head2));
     66     cnt = cnt2 = 0;
     67 }
     68 void add(int u,int v,int w)
     69 {
     70     ed[cnt].v = v;
     71     ed[cnt].w = w;
     72     ed[cnt].n = head[u];
     73     head[u] = cnt++;
     74     ed2[cnt2].v = u;
     75     ed2[cnt2].w = w;
     76     ed2[cnt2].n = head2[v];
     77     head2[v] = cnt2++;
     78 }
     79 int h[N];
     80 bool vis[N];
     81 void spfa(int s,int n)
     82 {
     83     queue<int>q;
     84     memset(vis,0,sizeof(vis));
     85     for (int i = 1; i <= n; ++i)
     86         h[i] = inf;
     87     q.push(s);
     88     h[s] = 0;
     89     vis[s] = true;
     90     while (!q.empty())
     91     {
     92         int u = q.front();
     93         q.pop();
     94         vis[u] = false;
     95         for (int i=head2[u];~i;i=ed2[i].n)
     96         {
     97             int v = ed2[i].v,w = ed2[i].w;
     98             if (h[v]>h[u]+w)
     99             {
    100                 h[v] = h[u] + w;
    101                 if (!vis[v])
    102                 {
    103                     vis[v] = true;
    104                     q.push(v);
    105                 }
    106             }
    107         }
    108     }
    109 }
    110 int ans[N];
    111 void astar(int s,int t,int k)
    112 {
    113     priority_queue<node2> q;
    114     int cnt = 0, dx = 0;
    115     node2 n,n2;
    116     ll m1=0,m2=0;
    117     sc(s,m1,m2);
    118     st[dx].p = -1,st[dx].v = s;
    119     n.set(s,0,h[s],dx++,m1,m2);
    120     q.push(n);
    121     while (!q.empty())
    122     {
    123         n = q.top();
    124         q.pop();
    125         if (n.v == t) cnt++;
    126         if (cnt == k)
    127         {
    128             int a = n.dx, b = 0;
    129             while (~a)
    130             {
    131                 ans[b++] = st[a].v;
    132                 a = st[a].p;
    133             }
    134             printf("%d %d
    ",n.g,b);
    135             bool ff = false;
    136             for (int i = b-1; i >= 0; --i)
    137             {
    138                 if (ff) printf(" ");
    139                 else ff = true;
    140                 printf("%d",ans[i]);
    141             }puts("");
    142             return ;
    143         }
    144         for (int i=head[n.v];~i;i=ed[i].n)
    145         {
    146             int v = ed[i].v, w = ed[i].w;
    147             m1 = n.m1, m2 = n.m2;
    148             if (ck(v,m1,m2)) continue;
    149             sc(v,m1,m2);
    150             st[dx].p = n.dx, st[dx].v = v;
    151             n2.set(v,n.g+w,n.g+w+h[v],dx++,m1,m2);
    152             q.push(n2);
    153         }
    154     }
    155     return ;
    156 }
    157 int main()
    158 {
    159     //read;
    160     int n,m,k;
    161     while (~scanf("%d%d%d",&n,&m,&k))
    162     {
    163         init();
    164         int u,v,w,s,t;
    165         for (int i = 0; i < m; ++i)
    166         {
    167             scanf("%d%d%d",&u,&v,&w);
    168             add(u,v,w);
    169         }
    170         scanf("%d%d",&s,&t);
    171         spfa(t,n);
    172         astar(s,t,k);
    173     }
    174     return 0;
    175 }
    View Code
  • 相关阅读:
    机器学习中常见的优化算法
    linux端安装Anaconda,方便远端访问jupyter
    核心③自动分号插入
    setTimeout 和 setInterval
    核心②undefined 和 null
    类型④类型转换
    核心①为什么不要使用 eval
    类型③instanceof 操作符
    类型①相等与比较
    类型②typeof 操作符
  • 原文地址:https://www.cnblogs.com/mcflurry/p/5069083.html
Copyright © 2020-2023  润新知