专栏文章

题解:P8653 [蓝桥杯 2017 国 C] 分考场(假题:最小色数)

P8653题解参与者 15已保存评论 19

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
19 条
当前快照
1 份
快照标识符
@mippwzyh
此快照首次捕获于
2025/12/03 16:01
3 个月前
此快照最后确认于
2025/12/03 16:01
3 个月前
查看原文
如题,这是一道假题。
实践得出贪心是假的,所以应该只有 O(nn)O(n^n) 的爆搜做法有正确性,然而剪枝能过全靠逆天数据。
听说复杂度已经高上天,常数就卡了一遍又一遍(?
既然不愿意写搜索,那么不妨写一个乱搞做法(笑)

我们充分发扬人类智慧:
将所有人全部赋上一个权值,然后按权值排序。
根据数学直觉,在此时跑一个贪心后,答案距离正解肯定不会离得太远。
所以我们只需要多随机赋几次权值来计算答案。
这样速度快得飞起,在 n=100n=100 时都可以在 1s 内卡过。

CPP
#include<bits/stdc++.h>
using namespace std;
vector<int>ve[105];
int a[105];
int ans;
int ret=1e9;
void dfs(int x){
    bitset<105>bi;
    bi.set();
    bi[0]=0;
    for(int i=0;i<ve[x].size();i++)
        bi[a[ve[x][i]]]=0;
    a[x]=bi._Find_first();
    ans=max(ans,a[x]);
}
struct fish{
    int x,id;
}flc[105];
bool cmp(fish l,fish r){
    return l.x<r.x;
}
int main(){
    srand(time(0));
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)flc[i].id=i;
    for(int i=1;i<=m;i++){
        int u,v;
        cin>>u>>v;
        ve[u].push_back(v);
        ve[v].push_back(u);
    }
    for(int r=1;r<=n;r++){
        memset(a,0,sizeof a);
        for(int i=1;i<=n;i++)flc[i].x=rand();
        sort(flc+1,flc+1+n,cmp);
        for(int i=1;i<=n;i++)dfs(flc[i].id);
        ret=min(ans,ret);
        ans=0;
    }
    cout<<ret;
    return 0;
}
这能过实在是太好笑了,有没有人来卡一下啊。

评论

19 条评论,欢迎与作者交流。

正在加载评论...