"Problem solution": y

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);
}
View Code

Guess you like

Origin www.cnblogs.com/xingmi-weiyouni/p/11606340.html