B3647 【模板】Floyd
1.思路:这是一道用floyd解决的模板题
2.代码:
#include <bits/stdc++.h>
using namespace std;
int f[105][105];
int main()
{
int n,m;
cin>>n>>m;
memset(f,0x3f3f3f3f,sizeof(f));
for(int i=1;i<=m;i=i+1)
{
int u,v,w;
cin>>u>>v>>w;
f[u][v]=w;
f[v][u]=w;
}
for(int i=1;i<=n;i=i+1)
{
f[i][i]=0;
}
for(int k=1;k<=n;k=k+1)
{
for(int v=1;v<=n;v=v+1)
{
for(int w=1;w<=n;w++)
{
if(f[v][w]>f[v][k]+f[k][w])
{
f[v][w]=f[v][k]+f[k][w];
}
}
}
}
for(int i=1;i<=n;i=i+1)
{
for(int j=1;j<=n;j=j+1)
{
if(j==1)
{
cout<<f[i][j];
}
else
{
cout<<" "<<f[i][j];
}
}
cout<<endl;
}
}
P4779 【模板】单源最短路径(标准版)
1.思路:这是用迪杰斯特拉算法做单源最短路径的标准化模板,里面用到了链式前向星的空间优化以及用优先队列的堆优化,降低了时间复杂度。
2.代码:
#include <bits/stdc++.h>
using namespace std;
int cnt;
int head[1000005];
int m,n,s;
int ans[1000005];
int vis[1000005];
struct edge
{
int to,wei,nextt;
}edge[1000005];
struct priority
{
int ans;
int id;
bool operator <(const priority &x)const
{
return x.ans<ans;
}
};
void addedge(int x,int y,int z)
{
edge[++cnt].to=y;
edge[cnt].wei=z;
edge[cnt].nextt=head[x];
head[x]=cnt;
}
priority_queue <priority> q;
int main()
{
cin>>m>>n>>s;
for(int i=1;i<=n;i=i+1)
{
ans[i]=0x3f3f3f3f;
}
ans[s]=0;
for(int i=1;i<=n;i=i+1)
{
int a,b,c;
cin>>a>>b>>c;
addedge(a,b,c);
}
int u;
q.push((priority){0,s});
while(!q.empty())
{
priority temp=q.top();
q.pop();
u=temp.id;
if(!vis[u])
{
vis[u]=1;
for(int i=head[u];i;i=edge[i].nextt)
{
int v=edge[i].to;
if(ans[v]>ans[u]+edge[i].wei)
{
ans[v]=ans[u]+edge[i].wei;
if(!vis[v])
{
q.push((priority){ans[v],v});
}
}
}
}
}
for(int i=1;i<=m;i=i+1)
{
cout<<ans[i]<<" ";
}
}
P2661 [NOIP2015 提高组] 信息传递
1.思路:其实我自己没啥思路,看了题解后发现许多人都用并查集来求最小环,当找父节点找了一圈后发现正好等于自己,这就说明构成了一个环,并且查找深度就是环的大小。
2.代码:
#include <bits/stdc++.h>
using namespace std;
int fa[200005];
int deep;
int ans=0x3f3f3f3f;
int f[200005];
int find(int x,int &deep)
{
deep++;
if(fa[x]==x)return x;
else
{
return find(fa[x],deep);
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i=i+1)
{
fa[i]=i;
}
for(int i=1;i<=n;i=i+1)
{
deep=0;
int f;
cin>>f;
int h=find(f,deep);
if(h==i)
{
ans=min(ans,deep);
}
else
{
fa[i]=f;
}
}
cout<<ans;
}
P1144 最短路计数
1.思路:求最短路用迪杰斯特拉算法的模板,但是我们需要在模板的基础上,添加求最短路径条数的代码。
2.代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int head[2000005];
int cnt;
long long ans[1000005];
int js[1000005];
bool vis[1000005];
int mod=100003;
struct bian
{
int to,wei,nextt;
}edge[2000005];
struct priority
{
int ans;
int id;
bool operator <(const priority &x)const
{
return x.ans<ans;
}
};
void addedge(int x,int y,int z)
{
edge[++cnt].to=y;
edge[cnt].wei=z;
edge[cnt].nextt=head[x];
head[x]=cnt;
}
priority_queue <priority> q;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i=i+1)
{
ans[i]=0x3f3f3f3f;
}
for(int i=1;i<=m;i=i+1)
{
int a,b;
int c=1;
cin>>a>>b;
addedge(a,b,c);
addedge(b,a,c);
}
ans[1]=0;
js[1]=1;
int u;
q.push((priority){0,1});
while(!q.empty())
{
priority temp=q.top();
q.pop();
u=temp.id;
int d=temp.ans;
if(!vis[u])
{
vis[u]=1;
for(int i=head[u];i;i=edge[i].nextt)
{
int v=edge[i].to;
if(d+edge[i].wei==ans[v])
{
js[v]=(js[u]+js[v])%mod;
}
if(ans[v]>ans[u]+edge[i].wei)
{
ans[v]=ans[u]+edge[i].wei;
js[v]=js[u];
if(!vis[v])
{
q.push((priority){ans[v],v});
}
}
}
}
}
for(int i=1;i<=n;i=i+1)
{
cout<<js[i]<<endl;
}
}
P8794 [蓝桥杯 2022 国 A] 环境治理
1.思路:题目中求经过的天数的最小值,并且可以发现天数是按递增的方式排序的,可以用二分进行查找,另外可以用floyd算法求出每两点之间的最短距离,最后叠加求出灰尘度。
2.代码:
#include <bits/stdc++.h>
using namespace std;
int d[105][105];
int li[105][105];
int n;
int q;
int check(int mid)
{
int tmp[105][105];
int i,j,k;
for (i =0; i<n; i++)
for (j =0; j<n; j++)
tmp[i][j]=d[i][j];
for (i =0; i<n; i++)
{
int v= mid/n+(mid%n>=i+1?1:0);
for (j =0 ; j<n; j++)
{
tmp[i][j]-=v;
if (tmp[i][j]<li[i][j]) tmp[i][j]=li[i][j];
tmp[j][i]-=v;
if (tmp[j][i]<li[j][i]) tmp[j][i]=li[j][i];
}
}
for (k =0 ; k<n; k++)
for (i =0 ; i<n; i++)
for (j =0 ; j<n; j++)
tmp[i][j]=min(tmp[i][j],tmp[i][k]+tmp[k][j]);
int res =0 ;
for (i =0; i<n; i++) // 计算治理后的P指标值
for (j =0; j<n; j++)
res+=tmp[i][j];
if(res<=q)
{
return 1;
}
else
{
return 0;
}
}
int find()
{
int l=0;
int r=100000*n;
while (l+1<r)
{
int mid=(l+r)/2;
if (check(mid))
{
r= mid;
}
else
l=mid;
}
return r;
}
int main()
{
cin>>n>>q;
int i,j;
for (i =0; i<n; i++)
for (j =0 ; j<n; j++)
scanf("%d",&d[i][j]);
for (i =0; i<n; i++)
for (j =0 ; j<n; j++)
scanf("%d",&li[i][j]);
int h=find();
if(h==100000*n)
{
cout<<-1;
}
else
{
cout<<h;
}
}