首页 > 其他分享 >CSP历年复赛题-P1078 [NOIP2012 普及组] 文化之旅

CSP历年复赛题-P1078 [NOIP2012 普及组] 文化之旅

时间:2024-05-31 17:12:04浏览次数:14  
标签:文化 dist NOIP2012 int ans P1078 100 CSP 105

原题链接:https://www.luogu.com.cn/problem/P1078

题意解读:1~n个国家,每个国家有自己的文化,不同国家文化可以相同,要从起点遍历到终点,已经学习过的文化不能重复学习,已经学习过的文化被某个文化歧视的国家也不能遍历,且不同国家之间有边,边有不同的距离,计算从起点到终点的最短路径。

解题思路:

分析题意,要遍历起点到终点,有两种方式:DFS、BFS,BFS通常用来计算的最短路要求边长都一样,也就是主要计算的最短路是第几层。

而本题每条边距离不等,因此考虑通过DFS所有所有的路径,从中求最短的距离。

分析复杂度:点最多100,边最多10000,文化最多100,DFS搜索有所路径的复杂度是O(100^100),每次到一个点要判断是否歧视已经学习的所有文化,总体时间复杂度在O(100^100*100),会超时。先实现代码,然后再优化!

60分代码:

#include <bits/stdc++.h>
using namespace std;

int n, k, m, s, t;
int diss[105][105]; //文化歧视表
int c[105]; //国家的文化
struct node
{
    int u; //起点
    int v; //终点
    int d; //u到v的距离
};
vector<node> g[105]; //领接表
bool vis[105];
int ans = INT_MAX;

void dfs(int u, int dist)
{
    if(u == t)
    {
        ans = min(ans, dist);
        return;
    }
    for(int i = 0; i < g[u].size(); i++)
    {
        int v = g[u][i].v;
        if(vis[c[v]]) continue; //如果文化已经学过,不重复学
        bool qishi = false;
        for(int j = 1; j <= k; j++)
        {
            if(vis[j] && diss[c[v]][j]) //已经学到的文化被v国文化歧视
            {
                qishi = true;
                break;
            }
        }
        if(qishi) continue; //被文化歧视,则不能经过
        vis[c[v]] = 1;
        dfs(v, dist + g[u][i].d);
        vis[c[v]] = 0;
    }
}

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 >> diss[i][j];
    int u, v, d;
    for(int i = 1; i <= m; i++)
    {
        cin >> u >> v >> d;
        g[u].push_back({u, v, d});
        g[v].push_back({v, u, d});
    }
    vis[c[s]] = 1; //标记已学到起点的文化
    dfs(s, 0);
    if(ans != INT_MAX) cout << ans;
    else cout << -1;

    return 0;
}

此题性能提升的关键在暴搜,需要考虑一种有效的剪枝策略,减少搜索的层级。

只需要用数组f[]记录每次遍历到的点时的距离,f[u] = dist

在dfs开始处,如果当前再次走到u点时的距离dist >= 之前保存过的f[u],则没有必要在继续走了,可以提前return

这样一来就大大减少的暴搜的次数。

100分代码:

#include <bits/stdc++.h>
using namespace std;

int n, k, m, s, t;
int diss[105][105]; //文化歧视表
int c[105]; //国家的文化
struct node
{
    int u; //起点
    int v; //终点
    int d; //u到v的距离
};
vector<node> g[105]; //领接表
bool vis[105];
int f[105]; //记录到某个点的距离
int ans = INT_MAX;

void dfs(int u, int dist)
{
    if(dist >= f[u]) return;
    f[u] = dist;
    if(u == t)
    {
        ans = min(ans, dist);
        return;
    }
    for(int i = 0; i < g[u].size(); i++)
    {
        int v = g[u][i].v;
        if(vis[c[v]]) continue; //如果文化已经学过,不重复学
        bool qishi = false;
        for(int j = 1; j <= k; j++)
        {
            if(vis[j] && diss[c[v]][j]) //已经学到的文化被v国文化歧视
            {
                qishi = true;
                break;
            }
        }
        if(qishi) continue; //被文化歧视,则不能经过
        vis[c[v]] = 1;
        dfs(v, dist + g[u][i].d);
        vis[c[v]] = 0;
    }
}

int main()
{
    memset(f, 0x3f, sizeof(f));
    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 >> diss[i][j];
    int u, v, d;
    for(int i = 1; i <= m; i++)
    {
        cin >> u >> v >> d;
        g[u].push_back({u, v, d});
        g[v].push_back({v, u, d});
    }
    vis[c[s]] = 1; //标记已学到起点的文化
    dfs(s, 0);
    if(ans != INT_MAX) cout << ans;
    else cout << -1;

    return 0;
}

 

标签:文化,dist,NOIP2012,int,ans,P1078,100,CSP,105
From: https://www.cnblogs.com/jcwy/p/18224904

相关文章

  • 2024年第七届信息通信与信号处理国际会议(ICICSP 2024)即将召开!
    2024年第七届信息通信与信号处理国际会议(ICICSP2024)将于2024年9月21-23日在中国舟山举行。ICICSP2024是一个汇聚全球顶尖科研人才、探讨信息通信与信号处理领域最新科研成果和发展趋势的国际盛会。本次会议的主题涵盖了信号处理、多媒体信号处理、互联网技术等多个领域的前......
  • DVWA-CSP Bypass
    CSP的主要目标是减少和报告XSS攻击。XSS攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源—......
  • CSP历年复赛题-P1075 [NOIP2012 普及组] 质因数分解
    原题链接:https://www.luogu.com.cn/problem/P1075题意解读:求n的两个素因子中较大的一个。解题思路:数论的简单题,关键在于要知道一定有一个素因子不超过sqrt(n),而另一个素因子必然大于或等于sqrt(n),这样才能减少枚举时间。100分代码:#include<bits/stdc++.h>usingnamespaces......
  • WEB安全:Content Security Policy (CSP) 详解
    ContentSecurityPolicy(CSP)是一种强大的网页安全机制,用于防止跨站脚本(XSS)和其他注入攻击。通过设置一系列的内容安全策略,CSP可以限制网页可以加载的资源,从而保护用户数据和网站的安全性。什么是XSS攻击?跨站脚本攻击(XSS)是一种常见的安全漏洞,攻击者通过注......
  • CSP历年复赛题-P1310 [NOIP2011 普及组] 表达式的值
    原题链接:https://www.luogu.com.cn/problem/P1310题意解读:+代表按位或运算,*代表按位与运算,给定一个没有填数字的表达式,要求结果为0的数字方案数。解题思路:下面一步一步,由浅入深的来解决本题思路一(20分做法):观察得知,20%的数据,只有10个符号,且没有括号,也就是对应数字最多11个,可以......
  • CSP历年复赛题-P1308 [NOIP2011 普及组] 统计单词数
    原题链接:https://www.luogu.com.cn/problem/P1308题意解读:给定单词a,文本b,在b中找a的个数,并找a第一次出现的位置,注意b中任何位置可能含有多个连续空格。解题思路:通过双指针找b中每一个单词的首、尾位置i,j,与a进行一一比较即可。注意1:比较时不考虑大小写,可以统一转成小写字符tolo......
  • CSP历年复赛题-P1199 [NOIP2010 普及组] 三国游戏
    原题链接:https://www.luogu.com.cn/problem/P1199题意解读:人机轮流选将,电脑策略就是破坏可能和人已选能组成最大默契值的将,问人是否必胜,求出站的一对武将的默契值。解题思路:贪心题通常比较难以下手,经过分析,人肯定不可能选到每一行的最大默契值,因为电脑会破坏;进一步思考,那人能......
  • CCF-CSP真题《202403-1 词频统计》思路+python满分题解
    哇q(≧▽≦q),第一次写博客,请大家多多关照○| ̄|_ 看到没啥人提供202403的第一题解题思路及python代码,刚好写完,心血来潮想分享解题思路,就写下了这篇博客,有其他的编码版本,欢迎大家一起探讨呀(虽然我是算法菜鸟┗(T﹏T)┛,但有问题,我会尽力回答的!!!)好了废话不多说,上解题思路!大概想了......
  • 【CSP】202012-2 期末预测之最佳阈值
    2020年第21次CCF计算机软件能力认证  202012-2 期末预测之最佳阈值原题链接:期末预测之最佳阈值时间限制: 1.0秒空间限制: 512MiB目录题目背景题目描述输入格式输出格式样例1输入样例1输出样例1解释样例2输入样例2输出子任务解题思路AC代码期末预测之安......
  • CSP历年复赛题-P1190 [NOIP2010 普及组] 接水问题
    原题链接:https://www.luogu.com.cn/problem/P1190题意解读:n个人在m个水龙头排队接水,每个人接水量不同,接完水的排队的人可以接上,求总的接水时间。解题思路:1、先把前m个人安排在m个水龙头2、对于m后面的每一个人,都排在目前m个水龙头总接水时间最短的后面3、最后看m个水龙头最大......