2024.9.13

今日总结
1:做了一套初赛题,主要知识点如下:
one:DFS中一定要用到的数据结构是栈
two:有n个叶子节点的哈夫曼树中,其节点总数为2n – 1
three:TCP拥塞控制算法包括慢启动,拥塞避免,快速重传
2:Tractor S
将此题目的数据建一个图,求出每个的连通块,然后对连通块惊醒bfs搜索,其中注意连边的操作,最后求出到(0,0)点的最短路既是最后输出的答案

点击查看代码
#include<bits/stdc++.h>

using namespace std;

const int N = 4e5 + 10;
const int M = 1010;
const int inf = 1e7 + 10;

int n,tot;
int X,Y,head = 1,tail = 0;
int dis[N],a[M + 10][M + 10],num[M + 10][M + 10];
bool vis[M + 10][M + 10],f[N];
pair<int,int> q2[inf];
vector<pair<int,int>> e[N],p[N];
queue<pair<int,int>> q;
priority_queue <pair<int,int>,vector<pair<int,int>> ,greater<pair<int,int>>> pq;

int dx[5] = {0,1,0,-1};
int dy[5] = {-1,0,1,0};

int dijkstra()
{
    memset(f,0,sizeof(f));
    memset(dis,0x3f,sizeof(dis));
    dis[num[X][Y]] = 0;
    pq.push({0,num[X][Y]});
    while(!pq.empty())
    {
        int u = pq.top().second;
        pq.pop();
        if(f[u]) continue;
        f[u] = 1;
        for(int i = 0;i < e[u].size();i ++)
        {
            int v = e[u][i].first,w = e[u][i].second;
            if(dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                pq.push({dis[v],v});
            }
        }
    }
    return dis[num[0][0]];
}

void push(pair<int,int> pii)
{
    tail ++;
    tail %= 10000000;
    q2[tail] = pii;
}

void bfs(int x)
{
    for(int i = 0;i < p[x].size();i ++)
        push(p[x][i]),vis[p[x][i].first][p[x][i].second] = 1;
    while(head <= tail)
    {
        pair<int,int> pos = q2[head];
        head ++,head %= 10000000;
        for(int i = 0;i < 4;i ++)
        {
            int xx = pos.first + dx[i],yy = pos.second + dy[i];
            if(xx >= 0 && yy >= 0 && xx <= M && yy <= M && !vis[xx][yy])
            {
                push({xx,yy});
                vis[xx][yy] = 1;
                if(num[xx][yy] == 0)
                {   
                    num[xx][yy] = ++ tot;
                    e[num[pos.first][pos.second]].push_back({tot,a[xx][yy]});
                }
                else 
                {
                    for(int j = 0;j < p[num[xx][yy]].size();j ++)
                    {
                        int xxx = p[num[xx][yy]][j].first,yyy = p[num[xx][yy]][j].second;
                        if(!vis[xxx][yyy])
                        {
                            push({xxx,yyy});
                            vis[xxx][yyy] = 1;
                        }
                    }
                    e[num[pos.first][pos.second]].push_back({num[xx][yy],0});
                }
            }
        }
    }
}

void bfs_2(int x,int y)
{
    while(!q.empty()) q.pop();
    q.push({x,y});
    while(!q.empty())
    {
        pair<int,int> pos = q.front();
        q.pop();
        for(int i = 0;i < 4;i ++)
        {
            int xx = pos.first + dx[i],yy = pos.second + dy[i];
            if(xx >= x && yy >= 0 && xx <= M && yy <= M && !num[xx][yy] && a[xx][yy] == 0)
            {
                num[xx][yy] = tot;
                q.push({xx,yy});
            }
        }
    }
}

int main()
{
    memset(vis,0,sizeof(vis));
    memset(num,0    ,sizeof(num));
    memset(a,0,sizeof(a));
    scanf("%d %d %d",&n,&X,&Y);
    for(int i = 0;i < n;i ++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        a[x][y] ++;
    }
    for(int i = 0;i <= M;i ++)
    {
        for(int j = 0;j <= M;j ++)
        {
            if(!num[i][j] && a[i][j] == 0)
            {
                tot ++;
                num[i][j] = tot;
                bfs_2(i,j);
            }
        }
    }
    for(int i = 0;i <= M;i ++)
    {
        for(int j = 0;j <= M;j ++)
        {
            if(num[i][j])
                p[num[i][j]].push_back({i,j});
        }
    }
    bfs(num[X][Y]);
    printf("%d\n",dijkstra());
    return 0;
}

3:道路值守
一直跑最短路求解,在求解过程中更新每个节点的父节点的值,当找到符合条件的值以后dfs求解答案

点击查看代码
#include<bits/stdc++.h>

using namespace std;

const int N = 510;
const int M = 250010;

int n,m,ans,tot;
int f[N],head[N],nxt[M << 1],to[M << 1],dis[M << 1];
int fa[N][N],top[N];
bool ok[N];//判断边是否被访问

struct Node
{
    int x,dis;
    Node();
    Node(int xx,int dd)
    {
        x = xx,dis = dd;
    }
    bool operator<(const Node &a) const{return dis > a.dis;}
    bool operator>(const Node &a) const{return dis < a.dis;}
};

priority_queue<Node> q;

void add(int a,int b,int c)
{
    nxt[++ tot] = head[a];
    head[a] = tot;
    to[tot] = b;
    dis[tot] = c;
}

void bfs(int st)
{
    q.push(Node(st,0));
    while(!q.empty())
    {
        int x = q.top().x;
        q.pop();
        ok[x] = 0;
        for(int i = head[x];i;i = nxt[i])
        {
            int j = to[i];
            if(f[j] > f[x] + dis[i])
            {
                f[j] = f[x] + dis[i];
                top[j] = 1;//更新最短父节点
                fa[j][1] = x;
                if(ok[j]) continue;
                ok[j] = 1;
                q.push(Node(j,f[j]));//弹出所需要距离
            }
            else if(f[j] == f[x] + dis[i])
                fa[j][++ top[j]] = x;
        }
    }
}

void dfs(int x)
{
    ans ++;
    if(ok[x] || x == 0)
        return;
    ok[x] = 1;
    for(int i = 1;i <= top[x];i ++)
        dfs(fa[x][i]);//深搜子节点
}

int main()
{
    scanf("%d %d",&n,&m);
    int x,y,z;
    for(int i = 1;i <= m;i ++)
    {
        scanf("%d %d %d",&x,&y,&z);
        add(x,y,z),add(y,x,z);
    } 
    for(int i = 1;i <= n;i ++)
    {
        memset(f,0x3f,sizeof(f));
        memset(fa,0,sizeof(fa));
        memset(top,0,sizeof(top));
        memset(ok,0,sizeof(ok));
        f[i] = 0,ok[i] = 1;//初始化
        bfs(i);
        for(int j = i + 1;j <= n;j ++)
        {
            memset(ok,0,sizeof(ok));
            ans = 0;
            for(int k = 1;k <= top[j];k ++)//循环k次路径
                dfs(fa[j][k]);
            printf("%d ",ans);
        }
    }
    return 0;
}
posted @ 2024-09-13 21:34  Kevinhwbb  阅读(10)  评论(0编辑  收藏  举报