图论(一)

图论的基础:DFS,BFS,树与图的遍历,拓扑排序。

DFS的重要思想:搜索顺序以及剪枝,剪枝能大大提升搜索效率。

DFS的存储数据结构的系统的栈。

一般的BFS的存储数据结构是queue(不考虑迭代加深等情况)

在时间复杂度来说,DFS的效率来说是(n+1)!,而BFS的效率是2^(n*2)。

但是BFS适合用来解决部分最短路问题,这是DFS的一个缺陷。

树和图的深度遍历用DFS去解决问题

而层序遍历便用BFS.

拓扑排序:
定理:在一个不成环的有向图,存在拓扑序列

思路:用一个queue来存储拓扑序列,一个用来宽搜,先用找入度为0的点,存入搜索队列和存储队列,再像BFS那样去搜索,然后存入存储队列。

板子题:

AcWing844

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e3;

int n,m,ans;
int a[N][N],d[N][N];
int dx[4] = {1,0,-1,0},dy[4] = {0,1,0,-1};

int bfs(){
    queue<pair<int,int>>q;
    memset(d,-1,sizeof(d));
    d[1][1] = 0;
    q.push({1,1});
    while(!q.empty()){
       auto t = q.front();
       q.pop();
       int x,y;
       for(int i = 0;i < 4;i++){
           x = t.first + dx[i];
           y = t.second + dy[i];
           if(x >= 1 && x <= n && y >= 1 && y <= m && a[x][y] == 0 && d[x][y] == -1){
             d[x][y] = d[t.first][t.second] + 1;
             q.push({x,y});
           }
       }  
    }
    return d[n][m];
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++){
            cin >> a[i][j];
        }
    }    
    cout << bfs() << endl;
    return 0;
}

Acwing846

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;

int n,ans=N;
bool vis[N];
vector<int>a[N];

int dfs(int x){
    vis[x] = true;
    int sum = 1,res = 0;
    for(auto j : a[x]){
        if(!vis[j]){
            int s = dfs(j);
            res = max(s,res);
            sum += s; 
        }
    }
    res = max(res,n-sum);
    ans = min(res,ans);
    return sum;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    for(int i = 0;i < n-1;i++){
        int u,v;
        cin >> u >> v;
        a[u].push_back(v);
        a[v].push_back(u);
    }
    dfs(1);
    cout << ans << endl;    
    return 0;
}

AcWing847

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5+5;

int n,m,ans;
bool vis[N];
vector<int>a[N];
int d[N];

int bfs(){
    queue<int>q;
    memset(d,-1,sizeof(d));
    d[1] = 0;
    q.push(1);
    while(!q.empty()){
        int t = q.front();
        q.pop();
        for(auto j : a[t]){
            if(d[j] == -1){
               d[j] = d[t] + 1;
               q.push(j);
            }
        }
    }
    return d[n];
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for(int i = 0;i < m;i++){
        int u,v;
        cin >> u >> v;
        a[u].push_back(v);
    }
    cout << bfs() << endl;
    return 0;
}

AcWing848:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;

int n,m;
int d[N];
vector<int>a[N];
queue<int>q;
queue<int>p;
bool topsort(){
     for(int i = 1;i <= n;i++){
        if(!d[i]){
            q.push(i);
            p.push(i);
        }
     }
     while(!q.empty()){
        int t = q.front();
        q.pop();
        for(auto j : a[t]){
            d[j]--;
            if(d[j] == 0){
                q.push(j);
                p.push(j);
            }
        }
    }
    return p.size() == n;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for(int i = 0;i < m;i++){
        int u,v;
        cin >> u >> v;
        a[u].push_back(v);
        d[v]++;
    }
    if(topsort()){
        while(!p.empty()){
            cout << p.front() << " ";
            p.pop();
        }
    }
    else{
        cout << "-1" << endl;
    }    
    return 0;
}

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值