单源最短路的建图方式

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;
}
相关推荐
做人不要太理性8 分钟前
【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
c++·哈希算法·散列表·unordered_map·unordered_set
程序员-King.17 分钟前
2、桥接模式
c++·桥接模式
chnming198721 分钟前
STL关联式容器之map
开发语言·c++
VertexGeek24 分钟前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz24 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
程序伍六七34 分钟前
day16
开发语言·c++
小陈phd1 小时前
Vscode LinuxC++环境配置
linux·c++·vscode
火山口车神丶1 小时前
某车企ASW面试笔试题
c++·matlab
jiao_mrswang1 小时前
leetcode-18-四数之和
算法·leetcode·职场和发展
qystca1 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法