单源最短路的建图方式

1.https://www.acwing.com/problem/content/922/

考虑对每一个线路内部互相连权值为1的边再跑个单源点最短路即可。这里权值都是1,跑个BFS即可

AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int m,n;
bool g[510][510];
int dis[510];
int stop[510];
void bfs(){
	 memset(dis, 0x3f, sizeof dis);
	 queue<int> q;
	 dis[1]=0;
	 q.push(1);
	 while(!q.empty()){
	 	int ck=q.front();
	 	q.pop();
	 	for(int i=1;i<=n;i++){
	 		if(g[ck][i]&&dis[i]>dis[ck]+1){
	 			dis[i]=dis[ck]+1;
	 			q.push(i);
			 }
		 }
	 }
}
int main(){
	cin>>m>>n;
	string line;
	getline(cin,line);//过滤回车
	while(m--){
		getline(cin, line);
		stringstream ssin(line);
		int cnt=0,p;
		while(ssin>>p) stop[++cnt]=p;
		for(int i=1;i<=cnt;i++){
			for(int j=i+1;j<=cnt;j++){
				g[stop[i]][stop[j]]=1;
			}
		}
	}
	bfs();
	
    if (dis[n] == 0x3f3f3f3f) puts("NO");
    else cout << max(dis[n] - 1, 0) << endl; 
}

2.https://www.acwing.com/problem/content/905/

我们考虑每一个物品当作点,用另一件替换它另需的花费作为有权边,再建立一个超级源点与每一个点相连表示直接购买的花费,于是我们从他跑到1即可。

注意等级差距限制的调件,由于1一定满足,我们直接暴力枚举以他为右端点到以他为左端点的一系列区间即可。

AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int m,n;
int p[110],l1[110],x;
struct node{
    int dian,w;
};
vector<node> edge[111];
int dis[210];
int st[110];
int spfa(int l,int r)
{
    queue<int> q;
    memset(dis, 0x3f, sizeof dis);
    memset(st,0,sizeof(st));
    dis[0] = 0;
    st[0] = true;
    q.push(0);
  //  if(l[1]<=r&&l[1]>=l) dis[0]=0;
    while (!q.empty())
    {
        int t =q.front();
        q.pop();
        st[t] = 0;
        for (int i = 0; i <edge[t].size(); i++)
        {
            int j = edge[t][i].dian;
            if ((dis[j]>dis[t]+edge[t][i].w)&&(l1[j]<=r&&l1[j]>=l))
            {
                dis[j] = dis[t] + edge[t][i].w;
                if (!st[j])  
                {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }
    return dis[1];
}

int main(){
    cin>>m>>n;
    for(int i=1;i<=n;i++){
        cin>>p[i]>>l1[i]>>x;
        edge[0].push_back({i,p[i]});
        for(int j=1;j<=x;j++){
            int t,v;
            cin>>t>>v;
            edge[t].push_back({i,v});
        }
    }
    l1[0]=l1[1];
    int res=1e9;
    for(int i=l1[1]-m;i<=l1[1];i++){
        res=min(res,spfa(i,i+m));
    }
    cout<<res;
}
相关推荐
努力学习编程的伍大侠4 分钟前
基础排序算法
数据结构·c++·算法
TENET信条11 分钟前
代码随想录 day50 第十一章 图论part01
图论
XiaoLeisj32 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
yuyanjingtao1 小时前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
TENET信条1 小时前
代码随想录 day52 第十一章 图论part03
图论
charlie1145141911 小时前
C++ STL CookBook
开发语言·c++·stl·c++20
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode