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;
}