码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1138 POI2009 Baj 最短回文路 BFS

时间:2015-05-19 22:51:45      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:bzoj   bzoj1138   bfs   

+题目大意:给定一张有向图,每个点有一个字符,多次求两点的最短回文路

据说这道题第一次做的人都会T?
一开始的思路是这样的:令fx,y表示从点x走到点y的最短回文路径,转移fx,y=min{fz,w+2|x?c?>z,w?c?>y}
然后广搜,果断T了= =

冗余的转移太多了……
正解是这样的:
gx,y,c表示从点x走到点y,除了最后一条边之外是回文路径且最后一条边的字符为c的最短路
然后转移是这样的:
gx,y,c=min{fx,z+1|z?c?>y}
fx,y=min{gz,y,c+1|x?c?>z}
这样的复杂度是O(nm+26n2)的,就可以通过了

#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 440
using namespace std;
struct abcd{
    int to,c,next;
}table[60600];
int head[M],tot;
int n,m;
int f[M][M],g[M][M][26];
pair<pair<int,int>,int> q[M*M*27];
int r,h;
vector<int> a[M][26];
void Add(int x,int y,int z)
{
    table[++tot].to=y;
    table[tot].c=z;
    table[tot].next=head[x];
    head[x]=tot;
}
void BFS()
{
    vector<int>::iterator it;
    int i;
    while(r!=h)
    {
        pair<pair<int,int>,int> temp=q[++h];
        int x=temp.first.first,y=temp.first.second;
        if(temp.second==-1)
        {
            for(i=head[y];i;i=table[i].next)
                if(g[x][table[i].to][table[i].c]==-1)
                    g[x][table[i].to][table[i].c]=f[x][y]+1,q[++r]=make_pair(make_pair(x,table[i].to),table[i].c);
        }
        else
        {
            for(it=a[x][temp.second].begin();it!=a[x][temp.second].end();it++)
                if(f[*it][y]==-1)
                    f[*it][y]=g[x][y][temp.second]+1,q[++r]=make_pair(make_pair(*it,y),-1);
        }
    }
}
int main()
{
    int i,x,y;
    char p[10];
    cin>>n>>m;
    memset(f,-1,sizeof f);
    memset(g,-1,sizeof g);
    for(i=1;i<=n;i++)
        f[i][i]=0,q[++r]=make_pair(make_pair(i,i),-1);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%s",&x,&y,p+1);
        Add(x,y,p[1]-‘a‘);
        a[y][p[1]-‘a‘].push_back(x);
        if(~f[x][y]) continue;
        f[x][y]=1,q[++r]=make_pair(make_pair(x,y),-1);
    }
    BFS();
    static int a[M],d;
    cin>>d;
    for(i=1;i<=d;i++)
        scanf("%d",&a[i]);
    for(i=2;i<=d;i++)
        printf("%d\n",f[a[i-1]][a[i]]);
    return 0;
}

BZOJ 1138 POI2009 Baj 最短回文路 BFS

标签:bzoj   bzoj1138   bfs   

原文地址:http://blog.csdn.net/popoqqq/article/details/45848291

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!