zoukankan      html  css  js  c++  java
  • HDU4511 AC自动机+dijkstra

    题意:

    Description

      终于放寒假了,小明要和女朋友一起去看电影。这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则: 
      1、假设小明在的位置是1号点,女朋友在的位置是n号点,则他们之间有n-2个点可以走,小明每次走的时候只能走到比当前所在点编号大的位置; 
      2、小明来的时候不能按一定的顺序经过某些地方。比如,如果女朋友告诉小明不能经过1 -> 2 -> 3,那么就要求小明来的时候走过的路径不能包含有1 -> 2 -> 3这部分,但是1 -> 3 或者1 -> 2都是可以的,这样的限制路径可能有多条。 
      这让小明非常头痛,现在他把问题交给了你。 
      特别说明,如果1 2 3这三个点共线,但是小明是直接从1到3然后再从3继续,那么此种情况是不认为小明经过了2这个点的。 
      现在,小明即想走最短的路尽快见到女朋友,又不想打破女朋友的规定,你能帮助小明解决这个问题吗?

    Input

      输入包含多组样例,每组样例首先包含两个整数n和m,其中n代表有n个点,小明在1号点,女朋友在n号点,m代表小明的女朋友有m个要求; 
      接下来n行每行输入2个整数x 和y(x和y均在int范围),代表这n个点的位置(点的编号从1到n); 
      再接着是m个要求,每个要求2行,首先一行是一个k,表示这个要求和k个点有关,然后是顺序给出的k个点编号,代表小明不能走k1 -> k2 -> k3 ……-> ki这个顺序的路径; 
      n 和 m等于0的时候输入结束。 

       [Technical Specification] 
      2 <= n <= 50 
      1 <= m <= 100 
      2 <= k <= 5 

    Output

      对于每个样例,如果存在满足要求的最短路径,请输出这个最短路径,结果保留两位小数;否则,请输出”Can not be reached!” (引号不用输出)。
     
      1 #include <bits/stdc++.h>
      2 #include <cstdio>
      3 #include <iostream>
      4 #include <algorithm>
      5 #define ll long long
      6 #define lson l, m, rt<<1
      7 #define rson m+1, r, rt<<1|1
      8 #define st first
      9 #define nd second
     10 #define mp make_pair
     11 #define pii pair<int, int>
     12 #define pdi pair<double, int>
     13 #define gg puts("gg");
     14 //#define local
     15 //#define out1
     16 using namespace std;
     17 const int N  = 6e4+10;
     18 const int inf = 0x3f3f3f3f;
     19 int id(int c){
     20     return c-1;
     21 }
     22 struct Tire{
     23     int nex[N][50], fail[N],end[N], ch[N];
     24     int root, L, tot;
     25     int newnode(){
     26         memset(nex[L], -1, sizeof(nex[L]));
     27         end[L] = 0;
     28         ch[L] = 0;
     29         return L++;
     30     }
     31     void init(){
     32         L = tot = 0;
     33         root = newnode();
     34     }
     35     void insert(int* s, int len, int tag){
     36         int now = root;
     37         for(int i = 0; i < len; i++){
     38             int p = id(s[i]);
     39             if(nex[now][p] == -1)
     40                 nex[now][p] = newnode();
     41             now = nex[now][p];
     42             ch[now] = p;
     43         }
     44         end[now] = tag;
     45     }
     46     void build(){
     47         queue<int> Q;
     48         fail[root] = root;
     49         for(int i = 0; i < 50; i++){
     50             int& u = nex[root][i];
     51             if(u == -1)
     52                 u = root;
     53             else{
     54                 fail[u] = root;
     55                 Q.push(u);
     56             }
     57         }
     58         while(!Q.empty()){
     59             int now = Q.front();
     60             Q.pop();
     61             for(int i = 0; i < 50; i++){
     62                 int& u = nex[now][i];
     63                 if(u == -1)
     64                     u = nex[ fail[now] ][i];
     65                 else{
     66                     fail[u] = nex[ fail[now] ][i];
     67                     end[u] |= end[ fail[u] ];
     68                     Q.push(u);
     69                 }
     70             }
     71         }
     72     }
     73 };
     74 Tire ac;
     75 ll x[55], y[55];
     76 double w[55][55];
     77 int s[10];
     78 vector< pdi > ve[505];
     79 priority_queue< pdi, vector< pdi >, greater< pdi > >Q;
     80 double d[505];
     81 double dijkstra(int S){
     82     int i, x;
     83     for(i = 0; i < 505; i++) d[i] = 1e30;
     84     Q.push(mp(d[S]=0,S));
     85     while(!Q.empty()){
     86         pdi t = Q.top(); Q.pop();
     87         if(d[x = t.nd] < t.st) continue;
     88         for(i = 0; i < ve[x].size(); i++)
     89             if(d[x]+ve[x][i].st < d[ve[x][i].nd]){
     90                 d[ve[x][i].nd] = d[x]+ve[x][i].st;
     91                 Q.push( mp(d[ve[x][i].nd], ve[x][i].nd) );
     92             }
     93     }
     94 }
     95 int main(){
     96     int n, m, ca = 1;
     97     while(~scanf("%d%d", &n, &m), n+m){
     98         for(int i = 1; i <= n; i++)
     99             scanf("%lld%lld", x+i, y+i);
    100         for(int i = 0; i <= n; i++)
    101             for(int j = 0; j <= n; j++) w[i][j] = 1e30;
    102         for(int i = 1; i <= n; i++)
    103             for(int j = i+1; j <= n; j++)
    104                 w[i][j] = sqrt( 1.0*(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]) );
    105 
    106         ac.init();
    107         for(int i = 1; i <= n; i++){
    108             s[0] = i;
    109             ac.insert(s, 1, 0);
    110         }
    111 
    112         for(int i = 1; i <= m; i++){
    113             int k; scanf("%d", &k);
    114             for(int j = 0; j < k; j++)
    115                 scanf("%d", s+j);
    116             ac.insert(s, k, 1);
    117         }
    118         ac.build();
    119         for(int i = 0; i < ac.L; i++) ve[i].clear();
    120         for(int i = 1; i < ac.L; i++){
    121             int u = ac.ch[i]+1;
    122             for(int j = u+1; j <= n; j++) {
    123                 int to = ac.nex[i][id(j)];
    124                 if(!ac.end[to]) ve[i].push_back( mp(w[u][j], to) );
    125             }
    126         }
    127 
    128         dijkstra(ac.nex[0][id(1)]);
    129         double ans = 1e30;
    130         for(int i = 1; i < ac.L; i++){
    131             if(ac.ch[i] == id(n))
    132                 ans = min(ans, d[i]);
    133         }
    134         if(ans < 1e25)
    135             printf("%.2f
    ", ans);
    136         else
    137             puts("Can not be reached!");
    138     }
    139     return 0;
    140 }

    后记:发现debug能力实在太弱了...调半天没看出来哪错了...代码能力不够啊!!!

  • 相关阅读:
    第二阶段冲刺第二天
    第二阶段冲刺第一天
    学习进度表_十四周
    购买图书
    学习进度表_十三周
    寻找水王续
    学习进度表_十二周
    《梦断代码》读后笔记_4
    找水王
    学习进度表_十一周
  • 原文地址:https://www.cnblogs.com/dirge/p/6012301.html
Copyright © 2011-2022 走看看