题解 | #[SCOI2010]游戏#

[SCOI2010]游戏

https://ac.nowcoder.com/acm/problem/20566

本题将每件装备的两个点连成线,变成图。如果某个区域里面的图是一个树的话证明有一个是取不到的数,这时候必然将最大的去掉才为最好啊。
如果不是一个数,也就是有一个或多个回路的话证明每个数都可以取到。那么最后取组成为数里面的最大数,取最大数里面的最小的那个数就是最早阶段的地方,这个地方就是答案。
可以使用DFS搜索,如果搜索过程中碰到了之后搜索过的而且不是父亲的点,证明出现了回路。如果没有这样的情况那么就需要去最大的数了。
#include <bits/stdc++.h>
 
 
using namespace std;
const int maxn = 1000000+10;
vector<int> edge[maxn];
bool vis[maxn];
int max_val;
int N;
 
int dfs(int x, int fa) {
    bool flag = 0;
    max_val = max(max_val, x);
    for (int i=0;i<edge[x].size();i++) {
        if (edge[x][i]==fa) continue;
        if (vis[edge[x][i]]) {flag = 1; continue;}
        vis[edge[x][i]] = true;
        if (dfs(edge[x][i], x)) 
            flag = 1;
    }
    return flag;
}
 
int main() {
    int x, y;
    int ans = INT_MAX;
    cin>>N;
    for (int i=0;i<N;i++) {
        cin>>x>>y;
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    ans = N+1;
    for (int i=1;i<=N+1;i++) {
        max_val = 0;
        if (vis[i]) continue;
        if (!dfs(i, 0)) {
            ans = min(ans, max_val);
        }
    }
    cout<<ans-1;
    return 0;
}
采用并查集的做法:使用并查集的时候如果合并的两个的根相同的话证明发生了回路的情况,那么就将根部的状态变成1证明有回路。如果不同的话就变成两个根状态的或值,因为如果有回路的话合并后同样受感染有了回路。之后再根的地方记录其最大值即可。
#include <bits/stdc++.h>


using namespace std;
const int maxn = 10000+10;
int a[maxn], b[maxn], max_val[maxn];
int N;

int find(int x) {
    return a[x]==x? x:a[x] = find(a[x]);
}
int main() {
    int x, y;
    cin>>N;
    for (int i=1;i<=maxn-1;i++) {
        a[i] = i; max_val[i] = i;
        b[i] = 0;
    }
    for (int i=1;i<=N;i++) {
        cin>>x>>y;
        int rootx = find(x);
        int rooty = find(y);
        if (rootx != rooty) {
            a[rootx] = rooty;
            max_val[rooty] = max(max_val[rooty], max_val[rootx]);
            b[rooty] =(b[rooty] || b[rootx]);
        } else {
            b[rooty] = 1;
        }
    }
    int ans = 10001;
    //找最小截断
    for (int i=1;i<=maxn-1;i++) {
        if (a[i]==i && b[i]==0) {
            ans = min(ans, max_val[i]);
        }
    }
    cout<<ans-1;
    return 0;
}


全部评论

相关推荐

08-12 09:16
Java
牛客38753147...:后端的竞争者一届比一届卷,前两年非985还很多,一段大厂实习就已经非常优秀了。 现在985硕多如狗,人手一段大厂实习,而且腾讯和百度今年都宣布实习扩招了一倍不止,越来越多的人从本一研一就开始刷实习,信息差也基本没有了。可以预见的,以后只会越来越卷。
投递快手等公司10个岗位
点赞 评论 收藏
分享
真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务