2 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;
         
    }
    
    • 0
      @ 2026-8-6 21:14:18
      #include<bits/stdc++.h>
      using namespace std;
      const int N=110,INF=0x3f3f3f3f;
      int n,k,m,s,t;
      int c[N],dist[N];//文化和到某个国家的距离
      int a[N][N],g[N][N];//文化是否冲突和能否走到某个国家
      bool h[N];//是否学习过某个文化
      void dfs(int u,int d){
      	if(d>=dist[u]||d>=dist[t]) return ;
      	dist[u]=d;
      	if(u==t) return ;
      	for(int i=1;i<=n;i++){
      		if(g[u][i]==INF) continue;
      		if(h[c[i]]) continue;
      		bool flag=1;
      		for(int j=1;j<=k;j++){
      			if(h[j]&&a[j][c[i]]==1){
      				flag=0;
      				break;
      			}
      		}
      		if(flag){
      			h[c[i]]=1;
      			dfs(i,d+g[u][i]);
      			h[c[i]]=0;
      		}
      	}
      }
      int main(){
      	ios::sync_with_stdio(false);
      	cin.tie(nullptr);
      	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]]=1;
      	dfs(s,0);
      	if(dist[t]==INF){
      		cout<<-1;
      	}
      	else{
      		cout<<dist[t];
      	}
      	return 0;
      }
      
      • 1

      Information

      ID
      440
      Time
      1000ms
      Memory
      128MiB
      Difficulty
      6
      Tags
      # Submissions
      16
      Accepted
      6
      Uploaded By