B3647 【模板】Floyd
代码:
#include<bits/stdc++.h>
using namespace std;
int long long n,m,u,v,w,a[1001][1001];
/*n和m表示点的个数和边的条数,u为起点,v为终点,w为距离
a为模拟无向图的二维数组*/
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][j]=0x3f3f;
if(i==j)a[i][j]=0;
//初始化a
}
}
for(int i=1;i<=m;i++){
scanf("%lld%lld%lld",&u,&v,&w);
a[u][v]=w;
a[v][u]=w;
//读入每条路径起点和长度
}
for(int k=1;k<=n;k++){
//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]);
//比较是中转后的距离短还是直接去短
a[j][i]=a[i][j];
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%lld ",a[i][j]);
//输出表
}
printf("\n");
}
}
解析:
最短路径问题
P4779 【模板】单源最短路径(标准版)
代码:
#include<bits/stdc++.h>
#define M(x,y) make_pair(x,y)
using namespace std;
int fr[100010],to[200010],nex[200010],v[200010],tl,d[100010];
bool b[100010];
void add(int x,int y,int w){
to[++tl]=y;
v[tl]=w;
nex[tl]=fr[x];
fr[x]=tl;
}
priority_queue< pair<int,int> > q;
int main(){
int n,m,x,y,z,s;
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
for(int i=1;i<=n;i++) d[i]=1e10;
d[s]=0;
q.push(M(0,s));
while(!q.empty()){
int x=q.top().second;
q.pop();
if(b[x]) continue;
b[x]=1;
for(int i=fr[x];i;i=nex[i]){
int y=to[i],l=v[i];
if(d[y]>d[x]+l){
d[y]=d[x]+l;
q.push(M(-d[y],y));//懒得重载运算符
}
}
}
for(int i=1;i<=n;i++) printf("%d ",d[i]);
return 0;
}
模板
P2661 [NOIP2015 提高组] 信息传递
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
int dx[300000];//存每一个人传话的对象
bool visit[300000]={0},novisit[300000]={0};//visit存每次查找中被查到的点,而novisit存每次查找前,已经被查找过的点(及不用继续查找了)
int bs[300000]={0};//每次查找中第一次到一个节点所经过的边数
int minn=2e9;
void dfs(int node,int num)
{
if(novisit[node])return;//不需要继续找了
if(visit[node])//在此次查找中出现过
{
minn=min(minn,num-bs[node]);//形成一个环,取最小值
}
else
{
visit[node]=true;//在此次循环中经过
bs[node]=num;//记录第一次到达时的步数
dfs(dx[node],num+1);//搜索
novisit[node]=true;//已经搜过
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&dx[i]);
}
for(int i=1;i<=n;i++)
{
dfs(i,0);//枚举全部节点
}
printf("%d",minn);//输出
return 0;//时间复杂度O(n)
}
解析:
遍历
P1144 最短路计数
代码:
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1000000+1,maxm=2000000+1,INF=0x7f7f7f7f,MOD=100003;
vector<int>G[maxn];int dep[maxn];bool vis[maxn];int cnt[maxn];
int main(){
int N,M;scanf("%d%d",&N,&M);
for(int i=1;i<=M;i++){
int x,y;scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
queue<int>Q;dep[1]=0;vis[1]=1;Q.push(1);cnt[1]=1;
while(!Q.empty()){
int x=Q.front();Q.pop();
for(int i=0;i<G[x].size();i++){
int t=G[x][i];
if(!vis[t]){vis[t]=1;dep[t]=dep[x]+1;Q.push(t);}
if(dep[t]==dep[x]+1){cnt[t]=(cnt[t]+cnt[x])%MOD;}
}
}
for(int i=1;i<=N;i++){
printf("%d\n",cnt[i]);
}
return 0;
}
解析:
模板
P8794 [蓝桥杯 2022 国 A] 环境治理
代码:
#include <stdio.h>
#include <string.h>
int d[105][105];
int limit[105][105];
int n;
int min(int a,int b)
{
return a<b?a:b;
}
int calc(int day) // 计算经过day 天治理后的P指标值
{
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 val = day/n+(day%n>=i+1?1:0);
for (j =0 ; j<n; j++)
{
tmp[i][j]-=val;
if (tmp[i][j]<limit[i][j]) tmp[i][j]=limit[i][j];
tmp[j][i]-=val;
if (tmp[j][i]<limit[j][i]) tmp[j][i]=limit[j][i];
}
}
for (k =0 ; k<n; k++) // floyed 算法求最短路径
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];
return res ;
}
int main()
{
int q;
scanf("%d %d",&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",&limit[i][j]);
int left =0,right= 100000*n,ans =-1;
while (left<=right)
{
int mid = (left+right)/2;
if (calc(mid)<=q)
{
right= mid -1;
ans = mid;
}
else
left=mid+1;
}
printf("%d\n",ans);
return 0;
}
解析:
求最短路