第七周周报

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

解析:

求最短路

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值