备战蓝桥杯---搜索(完结篇)

再看一道不完全是搜索的题:

解法1:贪心+并查集:

把冲突事件从大到小排,判断是否两个在同一集合,在的话就返回,不在的话就合并。

下面是AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,m,a,b,c;
struct node{
    int x,y,qi;
}a1[100010];
int fa[50000];
bool cmp(node a,node b){
    return a.qi>b.qi;
}
int find(int x){
    if(fa[x]==x) return x;
    else return fa[x]=find(fa[x]);
}
void merge(int x,int y){
    fa[find(x)]=find(y);
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&a1[i].x,&a1[i].y,&a1[i].qi);
    }
    for(int i=1;i<=2*n+1;i++){
        fa[i]=i;
    }
    sort(a1+1,a1+1+m,cmp);
    int f=0;
    for(int i=1;i<=m;i++){
        int xx=a1[i].x;
        int yy=a1[i].y;
        if(find(xx)==find(yy)){
            cout<<a1[i].qi;
            f=1;
            break;
        }
        else{
            merge(xx,n+yy);
            merge(xx+n,yy);
        }
    }
    if(f==0) cout<<0;
}

解法2:二分+DFS

显然这是一个0/1单调函数,我们可以进行二分。那我们二分出值如何判断是否可行?

我们可以把有怨气值的连边,对每个联通块种的大于二分值的DFS,先把自己-》1,与他相连的赋为0,以此类推,看是否有两个0/1值相同并相连的节点。

下面是AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a,b,c,qi;
struct node{
    int aa,qi1;
};
vector<node> tu[20005];
int vis[20005];
int heibai[20005];
int dfs(int x,int fa,int mid){
    int f=0;
    vis[x]=1;
    heibai[x]=1-heibai[fa];
    for(int i=0;i<tu[x].size();i++){
    if(tu[x][i].qi1<=mid) continue;
    if(tu[x][i].aa==fa) continue;
    if(vis[tu[x][i].aa]==1&&heibai[tu[x][i].aa]==heibai[x]){
        f=1;
        continue;
    }
    if(vis[tu[x][i].aa]==1) continue;
    if(dfs(tu[x][i].aa,x,mid)==1) f=1;
   }
return f;
}
int check(int mid){
    memset(vis,0,sizeof(vis));
    memset(heibai,0,sizeof(heibai));
    int f=1;
    for(int i=1;i<=n;i++){
        if(vis[i]==1) continue;
        if(dfs(i,0,mid)==1){
            f=0;
            break;
        }
    }
    return f;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
       scanf("%d%d%d",&a,&b,&c);
        tu[a].push_back({b,c});
        tu[b].push_back({a,c});
        qi=max(qi,c);
    }
    int i=0,j=qi;
    while(i<j){
        int mid=(i+j)/2;
        if(check(mid)==1) j=mid;
        else i=mid+1;
    }
  
    cout<<i;
}
相关推荐
m0_720245013 小时前
1543.统计好三元组(简单)
开发语言·算法
To_OC3 小时前
LC 560 和为 K 的子数组:前缀和配哈希表,这对组合我是真的服了
javascript·算法·程序员
hans汉斯4 小时前
《软件工程与应用》期刊推荐&10月版面征稿中
图像处理·人工智能·深度学习·算法·音视频·软件工程
叠层归一研究院4 小时前
AGI 系统(八):符号范畴嵌入函子 — SymCat ↪ C_M107 严格化
c语言·开发语言·人工智能·算法·transformer·agi
其美杰布-富贵-李5 小时前
08 进阶评估指标与算法特定指标
人工智能·算法
.道阻且长.6 小时前
5.LeetCode算法习题讲解--双指针--有效三角形的个数
算法·leetcode·职场和发展
我是海飞6 小时前
杰理JL703N SSD1306 OLED(128x64) 点阵屏移植说明
单片机·算法·嵌入式·音频·杰理
wabs6667 小时前
关于图论【最短路径之Bellman_ford 算法(单源有限最短路)|卡码网96.城市间货物运输III的思考】
数据结构·算法·图论·卡码网·bellman_ford·单源有限最短路
会周易的程序员8 小时前
aiDgePLC — IEC61131-3 ST PLC 虚拟机调试与运行环境
c++·物联网·虚拟机·st·工业协议·iec61131·梯形图
lsylalalala9 小时前
常见的排序算法1
数据结构·算法·排序算法