4/1 最小生成树+最短路+floyed+图中深搜
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4/1 最小生成树+最短路+floyed+图中深搜相关的知识,希望对你有一定的参考价值。
P1194 买礼物
输入时需要特殊处理,若不加(x!=0),只能过一组样例,wa了三次,很烦~
数据中没有优惠是0,因此不同产品间若是0则不需要建边,但实际情况中是存在的,而且题目也没说,不纠结了。
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;
const int mod=998244353;
const int inf=0x3f3f3f3f;
int a,b,cnt,f[N],ans,g;
struct node
int u,v,dis;
e[N];
bool cmp(node e1,node e2)
return e1.dis<e2.dis;
int r_find(int r)
if(r==f[r]) return r;
f[r]=r_find(f[r]);
return f[r];
signed main()
ios::sync_with_stdio(0); cin.tie(0);
cin>>a>>b;
for(int i=1;i<=b;i++) f[i]=i;
for(int i=1;i<=b;i++)
for(int j=1;j<=b;j++)
int x;cin>>x;
if(j<=i||x==0) continue;
e[++cnt].u=i,e[cnt].v=j,e[cnt].dis=x;
for(int i=1;i<=b;i++)
e[++cnt].u=0,e[cnt].v=i,e[cnt].dis=a;
sort(e+1,e+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
int fx=r_find(e[i].u),fy=r_find(e[i].v);
if(fx==fy) continue;
g++;
f[fx]=fy;
ans+=e[i].dis;
if(g==b-1) break;
cout<<ans+a<<endl;
return 0;
P1346 电车
习惯了链式前向行,尽管这题不需要。
感觉spfa算法处理一般的最短路更方便点
#include <bits/stdc++.h>
using namespace std;
const int N=3e3+5;
const int mod=998244353;
const int inf=0x3f3f3f3f;
int n,a,b,dist[N],head[N],cnt;
bool vis[N];
struct node
int to,nxt,dis;
e[N*N];
void add(int from,int to,int dis)
e[++cnt].to=to;
e[cnt].dis=dis;
e[cnt].nxt=head[from];
head[from]=cnt;
void dijstra()
for(int i=1;i<=n;i++) dist[i]=inf;
dist[a]=0;
queue<int>q;q.push(a);vis[a]=1;
while(!q.empty())
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt)
int v=e[i].to;
if(dist[v]>dist[u]+e[i].dis)
dist[v]=dist[u]+e[i].dis;
if(!vis[v])
vis[v]=1;q.push(v);
signed main()
ios::sync_with_stdio(0); cin.tie(0);
cin>>n>>a>>b;
for(int i=1;i<=n;i++)
int k;cin>>k;
for(int j=1;j<=k;j++)
int x;cin>>x;
if(j==1)
add(i,x,0);
else
add(i,x,1);
dijstra();
if(dist[b]==inf)
cout<<"-1"<<endl;
else
cout<<dist[b]<<endl;
return 0;
P1476 休息中的小呆
光题意就挺难懂得。
1.共n个剧情点,要想到共有n+1个剧情。
2.采用floyed算最常路。因为要完成所有的剧情任务,如果需要时间最长的完成了,则其他的肯定也完成了!比较抽象。
3.由于是全源最短路,设置间断点看经过了哪些点
#include <bits/stdc++.h>
using namespace std;
const int N=1e2+5;
const int mod=998244353;
const int inf=0x3f3f3f3f;
int mp[N][N],dist[N],n,m;
signed main()
ios::sync_with_stdio(0); cin.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
int x,y,z;cin>>x>>y>>z;
mp[x][y]=z;
//n个剧情结束点,说明有n+1个剧情
for(int k=1;k<=n+1;k++)
for(int i=1;i<=n+1;i++)
for(int j=1;j<=n+1;j++)
if(i!=j&&j!=k&&mp[i][k]&&mp[k][j])
if(mp[i][j]<mp[i][k]+mp[k][j])
mp[i][j]=mp[i][k]+mp[k][j];
cout<<mp[1][n+1]<<endl;
for(int i=1;i<=n+1;i++)
if(mp[1][i]+mp[i][n+1]==mp[1][n+1])
cout<<i<<" ";
cout<<endl;
return 0;
P1661 扩散
floyed算法:根据两点间得曼哈顿距离建图
比较i到k
和k到j
中取较大得那个,最后结果/2.
#include <bits/stdc++.h>
using namespace std;
const int N=1e2+5;
const int mod=998244353;
const int inf=0x3f3f3f3f;
int mp[N][N],n,a[N],b[N],mx;
signed main()
ios::sync_with_stdio(0); cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i]>>b[i];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)
mp[i][j]=abs(a[i]-a[j])+abs(b[i]-b[j]);
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&j!=k&&mp[i][k]&&mp[k][j])
mp[i][j]=min(mp[i][j],max(mp[i][k],mp[k][j]));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
mx=max(mx,mp[i][j]);
cout<<(mx+1)/2<<endl;
return 0;
P1692 部落卫队
对于深搜得代码还是不够熟练。dfs中若是思路不够清晰,不要轻易写for循环,增加复杂度。
此代码数据范围大的过不了~
#include <bits/stdc++.h>
using namespace std;
const int N=1e2+5;
const int mod=998244353;
const int inf=0x3f3f3f3f;
int mp[N][N],n,m,ans,mx,a[N];
bool vis[N];
bool check(int x) //选的这个人于队里是否有矛盾
for(int i=1;i<=n;i++)
if(vis[i]&&mp[x][i]) return 0; //如果这个人之前选过并且和待选的人有仇,就不能选
return 1;
void dfs(int u,int num) //搜索到第几个人,队里人数
if(u==n+1) //搜索完所有人,结束
if(mx<num)
mx=num;
for(int i=1;i<=n;i++) //记录选人的状态
a[i]=vis[i];
return;
if(!vis[u]&&check(u)) //对于一个人选和不选,这里满足条件进入if语句可以选
vis[u]=1;
dfs(u+1,num+1);
vis[u]=0;
dfs(u+1,num); //不选
signed main()
ios::sync_with_stdio(0); cin.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
int u,v;cin>>u>>v;
mp[u][v]=1;mp[v][u]=1;
dfs(1,0); //从第一个人开始,队里没人
cout<<mx<<endl;
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
以上是关于4/1 最小生成树+最短路+floyed+图中深搜的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1016: [JSOI2008]最小生成树计数 深搜+并查集
数据结构与算法图最短路径算法 ( Floyed 算法 | 图最短路径算法使用场景 | 求解图中任意两个点之间的最短路径 | 邻接矩阵存储图数据 | 弗洛伊德算法总结 )