1 solutions

  • 1
    @ 2024-6-11 16:03:28

    搜索+剪枝(100pts)

    • 从前往后搜索每座城市,每次更新最短距离,如果当前分支不可能是答案,则提前结束当前节点。
    #include<bits/stdc++.h>
    using namespace std;
    const int N=110,K=110,INF=0x3f3f3f3f;
    int n,k,m,s,t;
    int c[N],dist[N]; //文化和到某个国家的距离
    int a[K][K],g[N][N]; //文化和国家之间的距离
    bool h[K]; //是否学习过某个文化
     
    void dfs(int u,int d)
    {
        if(d>=dist[u]||d>=dist[t]) return ; //当前距离已经大于已有距离
        dist[u]=d; //记录从起点到u国家的距离
        if(u==t) return ; //终点
        for(int i=1;i<=n;i++) //枚举每个国家
        {
            if(g[u][i]==INF) continue; //无路可走
            if(h[c[i]]) continue; //已经学习过该文化
            bool flag=true; //判断是否和之前的文化有冲突
            for(int j=1;j<=k;j++)
            {
                if(h[j]&&a[j][c[i]]==1) //学过文化j且和c[i]有冲突
                {
                    flag=false;
                    break;
                }
            }
            if(flag) //可以从u走到i
            {
                h[c[i]]=1; //学习c[i]文化 
                dfs(i,d+g[u][i]); //继续往下走 
                h[c[i]]=0; //清楚c[i]文化标记 
            }
        }
    }
    int main()
    {
        cin>>n>>k>>m>>s>>t;
        for(int i=1;i<=n;i++) cin>>c[i]; //获取每个国家的文化
        for(int i=1;i<=k;i++) //获取冲突文化
        {
            for(int j=1;j<=k;j++)
            {
                cin>>a[i][j];
            }
        }
        memset(dist,0x3f,sizeof dist);
        memset(g,0x3f,sizeof g);
        for(int i=1;i<=n;i++) g[i][i]=0;
        for(int i=1;i<=m;i++) //获取距离
        {
            int a,b,c;
            cin>>a>>b>>c;
            g[a][b]=g[b][a]=min(g[a][b],c);
        }
        h[c[s]]=true; //标记起点文化已经学过
        dfs(s,0); //从起点开始搜索
        if(dist[t]==0x3f3f3f3f) cout<<-1;
        else cout<<dist[t];
        return 0;
         
    }
    
    • 1

    Information

    ID
    440
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    10
    Tags
    # Submissions
    2
    Accepted
    2
    Uploaded By