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