Problem B: y
Time limit: 1 Sec Memory Limit: 256 MB
Face questions
He declined to publicly face the question.
answer
Consider bi-directional search.
Defined $ cal_ {i, j, k} $ represents the current state of the search whether or not there has been a length of i, end point j, the state side is searched state k.
Also a defined state design $ cal2_ {i, j, k} $. Search half of each array, violence can be transferred.
Consider Initialization: $ cal_ {i, j, k} $ array must be the starting point node, the initial value of $ cal_ {0,1,0} = 1 $.
And $ cal2_ {i, j, k} $ array arbitrary starting point. Thus $ cal_ {0, i, 0} = 1 (i \ in [1, n]) $.
Finally, consider the two halves of the state makes up a state enumeration breakpoint that is the final state, to determine whether there are two states can be spliced together to the current total state.
As for the direction of the splicing problems, you can define the state of $ cal2 $ array change it slightly: reverse search, the starting point for the current j, such a state can be reversed without cal2 of stitching. State transition unchanged.
$ Cal [21] [91] [(1 << 20) +10] $,: ( on why open search, if not open, so the array definition will be the size of 2,003,847,846 words state, that is not separated the number of explosive growth.)
#include<bits/stdc++.h> #define rint register int using namespace std; int n,m,d,ans,len,ren; bool cal[23][103][20003],cal2[23][103][20003]; vector < pair<int,int> > v[20003]; int main() { scanf("%d %d %d",&n,&m,&d);len=d/2,ren=d-len; cal[0][1][0]=1;for(rint i=1;i<=n;++i)cal2[0][i][0]=1; for(rint i=1,ST,EN,CL;i<=m;++i) { scanf("%d %d %d",&ST,&EN,&CL); v[ST].push_back(make_pair(EN,CL)); v[EN].push_back(make_pair(ST,CL)); } for(rint i=0;i<len;++i) for(rint j=0;j<(1<<i);++j) for(rint k=1;k<=n;++k) if(cal[i][k][j]) { for(rint q=0;q<v[k].size();++q) cal[i+1][v[k][q].first][(j<<1)+v[k][q].second]=1; } for(rint i=0;i<ren;++i) for(rint j=0;j<(1<<i);++j) for(rint k=1;k<=n;++k) if(cal2[i][k][j]) { for(rint q=0;q<v[k].size();++q) cal2[i+1][v[k][q].first][(j<<1)+v[k][q].second]=1; } for(rint i=0;i<(1<<d);++i)for(rint j=1;j<=n;++j) if(cal[len][j][i>>ren]&&cal2[ren][j][i&(1<<ren)-1]){ans++;break;} printf("%d\n",ans); }