HDU-4511-ac自動機+dp
阿新 • • 發佈:2018-05-03
當前 %d debug 保留 說明 必須 php cal pre
1、假設小明在的位置是1號點,女朋友在的位置是n號點,則他們之間有n-2個點可以走,小明每次走的時候只能走到比當前所在點編號大的位置;
2、小明來的時候不能按一定的順序經過某些地方。比如,如果女朋友告訴小明不能經過1 -> 2 -> 3,那麽就要求小明來的時候走過的路徑不能包含有1 -> 2 -> 3這部分,但是1 -> 3 或者1 -> 2都是可以的,這樣的限制路徑可能有多條。
這讓小明非常頭痛,現在他把問題交給了你。
特別說明,如果1 2 3這三個點共線,但是小明是直接從1到3然後再從3繼續,那麽此種情況是不認為小明經過了2這個點的。
現在,小明即想走最短的路盡快見到女朋友,又不想打破女朋友的規定,你能幫助小明解決這個問題嗎?
接下來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
小明系列故事——女友的考驗
Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 2024 Accepted Submission(s): 556
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!” (引號不用輸出)。
Sample Input 3 1 1 1 2 1 3 1 2 1 2 2 1 0 0 1 1 2 1 2 5 3 0 0 5 3 1 2 1 22 5 21 3 1 2 3 2 4 5 2 1 5 0 0
Sample Output 2.00 Can not be reached! 21.65
Source 2013騰訊編程馬拉松初賽第二場(3月22日) 將女友的要求建ac自動機,然後在樹上匹配,f[i][j]表示在i號點對應樹上的狀態j時候的最短路(從1開始),WA了半天原來是bfs的時候忘記把以失配指針的為結尾的單詞狀態轉移到當前節點上,比如1-2-3-4 ,2-3 , 第一條路徑上的‘3‘顯然應該被標記為不能走的路(由於包含了禁路"2-3"),= =還是掌握的不熟練啊。
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #include<cstdio> 5 #include<stack> 6 #include<set> 7 #include<map> 8 #include<cmath> 9 #include<ctime> 10 #include<time.h> 11 #include<algorithm> 12 using namespace std; 13 #define mp make_pair 14 #define pb push_back 15 #define debug puts("debug") 16 #define LL long long 17 #define pii pair<int,int> 18 #define eps 1e-10 19 double inf=1e20; 20 int N; 21 struct Point{ 22 double x,y; 23 }P[55]; 24 double dis(Point A,Point B){ 25 return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)); 26 } 27 double e[55][55]; 28 struct ach{ 29 int ch[1020][55],fail[1020],cnt[1020],tot; 30 double f[55][1020]; 31 void init(){ 32 tot=0; 33 newnode(); 34 } 35 36 int newnode(){ 37 memset(ch[tot],-1,sizeof(ch[tot])); 38 fail[tot]=-1; 39 cnt[tot]=0; 40 return tot++; 41 } 42 43 void insert(int a[],int n){ 44 int u=0; 45 for(int i=1;i<=n;++i){ 46 if(ch[u][a[i]]==-1) ch[u][a[i]]=newnode(); 47 u=ch[u][a[i]]; 48 } 49 cnt[u]=1; 50 } 51 void getfail(){ 52 queue<int>q; 53 fail[0]=0; 54 for(int i=1;i<=N;++i){ 55 if(ch[0][i]==-1){ 56 ch[0][i]=0; 57 } 58 else{ 59 fail[ch[0][i]]=0; 60 q.push(ch[0][i]); 61 } 62 } 63 while(!q.empty()){ 64 int u=q.front(); 65 q.pop(); 66 cnt[u]|=cnt[fail[u]]; 67 for(int i=1;i<=N;++i){ 68 if(ch[u][i]==-1){ 69 ch[u][i]=ch[fail[u]][i]; 70 } 71 else{ 72 fail[ch[u][i]]=ch[fail[u]][i]; 73 q.push(ch[u][i]); 74 } 75 } 76 } 77 } 78 79 void solve(){ 80 for(int i=1;i<=N;++i){ 81 for(int j=0;j<tot;++j){ 82 f[i][j]=inf; 83 } 84 } 85 f[1][ch[0][1]]=0; 86 for(int i=1;i<=N;++i){ 87 for(int j=0;j<tot;++j){ 88 if(f[i][j]<inf){ 89 for(int k=i+1;k<=N;++k){ 90 if(cnt[ch[j][k]]==0){ 91 f[k][ch[j][k]]=min(f[k][ch[j][k]],f[i][j]+e[i][k]); 92 } 93 } 94 } 95 } 96 } 97 98 double ans=inf; 99 for(int j=0;j<tot;++j) 100 ans=min(ans,f[N][j]); 101 if(ans==inf) puts("Can not be reached!"); 102 else printf("%.2f\n",ans); 103 } 104 }a; 105 int main() 106 { 107 int n,m,i,j,k; 108 int c[15]; 109 while(cin>>n>>m){N=n; 110 a.init(); 111 if(n==0&&m==0) break; 112 for(i=1;i<=n;++i) {e[i][i]=0; 113 scanf("%lf%lf",&P[i].x,&P[i].y); 114 for(j=1;j<i;++j){ 115 e[i][j]=e[j][i]=dis(P[i],P[j]); 116 } 117 } 118 for(i=1;i<=m;++i){ 119 scanf("%d",&k); 120 for(j=1;j<=k;++j){ 121 scanf("%d",c+j); 122 } 123 a.insert(c,k); 124 } 125 126 a.getfail(); 127 a.solve(); 128 } 129 return 0; 130 }
HDU-4511-ac自動機+dp