Week9-图
第一题(查找文献)
评析:存图后bfs加dfs就可以了,注意排序,这题不难
#include<bits/stdc++.h>
using namespace std;
int a[100007];
vector<vector<int> >vv;
int m,n;
void dfs(int x)
{
if(a[x]==1) return ;
cout<<x<<" ";
a[x]=1;
for(int i=0;i<vv[x].size();i++)
dfs(vv[x][i]);
}
void bfs()
{
queue<int> q;
memset(a,0,sizeof(a));
q.push(1);
a[1]=1;
while(!q.empty())
{
int f=q.front();
q.pop();
cout<<f<<" ";
for(int i=0;i<vv[f].size();i++)
{
if(a[vv[f][i]]==1) continue;
q.push(vv[f][i]);
a[vv[f][i]]=1;
}
}
}
int main()
{
memset(a,0,sizeof(a));
cin>>m>>n;
vector<int>w;
for(int i=0;i<=n;i++)
{
vv.push_back(w);
}
for(int i=0;i<n;i++)
{
int u,v;
cin>>u>>v;
vv[u].push_back(v);
}
for(int i=0;i<=n;i++)
sort(vv[i].begin(),vv[i].end());
dfs(1);
cout<<endl;
bfs();
}
第二题(floyd)
评析:模板题,背一下祝佬的模板三个循环再加上a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
#include<bits/stdc++.h>
using namespace std;
const int mod=998244354;
int n,m;
int f[505][505];
int a[505][505];
int main(){
cin>>n>>m;
memset(a,0x3f,sizeof(a));//记得先初始化为无穷大
for (int i=1; i<=n; i++) a[i][i]=0;
for (int i=1; i<=m; i++)
{
int u,v,w;
cin>>u>>v>>w;
a[u][v]=min(w,a[u][v]);
a[v][u]=min(w,a[v][u]);
}//邻接表存图
for (int k=1; k<=n; k++)
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);//floyd算法
int sum=0;
for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++)
{
sum=(sum+a[i][j])%mod;//取模
}
cout<<sum<<endl;
sum=0;
}
return 0;
}
第三题(dijkstra)
评析:视频里讲了,要注意链式前向星和优先队列和堆优化,可以大大简化时间
#include<bits/stdc++.h>
using namespace std;
struct edge
{
int to, dis, next;
};
edge e[500005];
int head[100005], dis[100005], cnt;
bool vis[100005];
int n, m, s;
inline void add_edge(int u, int v, int d)
{
cnt++;
e[cnt].dis = d;
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}//链式前向星存图
struct node
{
int dis;
int pos;
bool operator <(const node &x)const
{
return x.dis < dis;
}
};
std::priority_queue<node> q;
inline void dijkstra()
{
dis[s] = 0;
q.push(node{0, s});
while(!q.empty())
{
node tmp = q.top();
q.pop();
int x = tmp.pos, d = tmp.dis;
if(vis[x]) continue;
vis[x] = 1;
for( int i = head[x]; i; i = e[i].next)
{
int y = e[i].to;
if( dis[y] > dis[x] + e[i].dis )
{
dis[y] = dis[x] + e[i].dis;
if(!vis[y]) q.push( node{dis[y], y});
}
}
}
}//不断刷新最短路径
int main()
{
cin>>n>>m>>s;
for(int i = 1; i <= n; i++) dis[i] = 0x7fffffff;
for(int i = 0; i < m; i++)
{
int u, v, d;
cin>>u>>v>>d;
add_edge(u,v,d);
}
dijkstra();
for( int i = 1; i <= n; i++)
cout<<dis[i]<<" ";
return 0;
}
堆优化模板(借鉴了大佬的):
struct edge {
int v, w;
};
struct node {
int dis, u;
bool operator>(const node& a) const { return dis > a.dis; }
};
vector<edge> e[N];//邻接表存带权边
int dis[N], vis[N];//dis表示与起点距离,vis表示是否收录最短路径
priority_queue<node, vector<node>, greater<node> > q;//小顶堆,按照与起点距离排序
void dijkstra(int n, int s) {
memset(dis, 0x3f, sizeof(dis));
dis[s] = 0;
q.push({0, s});
while (!q.empty()) {
int u = q.top().u;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (auto ed : e[u]) {
int v = ed.v, w = ed.w;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
q.push({dis[v], v});
}
}
}
}