NOIP2012P4 文化之旅 题解

(题目描述略)

对于这道题,最好的方法是直接BFS,而大多数通过动归解决的算法都不太可能是完全正确的。

代码如下:

#include"stdio.h"
#include"string.h"
struct construction
{
    bool tc[105],td[105];//tc记录文化是否学习,td记录国家是否到达
    int now,sum;//now记录当前节点,sum记录当前路径长度
}q[50000];//模拟队列
int a[105][105],c[105],k,map[105][105],reflect[50000];
bool judge(int i,int j)
{
    for(int l=1;l<=k;l++)
        if(q[i].tc[l]&&a[c[j]][l]==1)
            return false;
    return true;
}
int main()
{
    freopen("culture.in","r",stdin);
    freopen("culture.out","w",stdout);
    memset(map,-1,sizeof(map));
    int ans=-1,m,n,s,t,top=1,u,v;
    scanf("%d %d %d %d %d",&n,&k,&m,&s,&t);
    for(int i=1;i<=n;i++)
        scanf("%d",&c[i]);
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=k;j++)
            scanf("%d",&a[i][j]);
        a[i][i]=1;
    }
    while(m--)
    {
        scanf("%d %d",&u,&v);
        scanf("%d",&map[u][v]);
        if(map[v][u]==-1||map[u][v]<map[v][u])
            map[v][u]=map[u][v];
    }
    reflect[0]=q[0].sum=0;
    q[0].now=s;
    q[0].tc[c[s]]=q[0].td[s]=true;
    for(int i=0;i<top;i++)
    {
        if(top>20000)
        {
            printf("-1");
            return 0;
        }
        if(q[reflect[i]].now==t)
        {
            ans=q[reflect[i]].sum;
            break;
        }
        for(int j=1;j<=n;j++)
            if(map[q[reflect[i]].now][j]!=-1&&!q[reflect[i]].td[j]&&judge(reflect[i],j))
            {
                q[top].now=j;
                q[top].sum=q[reflect[i]].sum+map[q[reflect[i]].now][j];
                for(int l=1;l<=k;l++)
                    q[top].tc[l]=q[reflect[i]].tc[l];
                for(int l=1;l<=n;l++)
                    q[top].td[l]=q[reflect[i]].td[l];
                q[top].tc[c[j]]=true;
                q[top].td[j]=true;
                reflect[top]=top++;//reflect调整节点搜索次序,使路径最短
                for(int l=top-2;i<l&&q[reflect[l]].sum>q[reflect[l+1]].sum;l--)
                    m=reflect[l],reflect[l]=reflect[l+1],reflect[l+1]=m;
            }
    }
    printf("%d",ans);
    return 0;
}

由于本题官方数据过弱,导致某些没有考虑文化相斥的算法也能通过。当然,由于笔者也因无正确数据而无法保证此程序对于考虑文化相斥数据的正确性。不过,此算法的思路是基于考虑文化相斥的,虽然时间较动归算法而言略慢,但仍不失为一种考虑周全的算法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值