单源最短路问题。

acwing 1129 热浪

#include<bits/stdc++.h>
using namespace std;
#define N 2510
#define M 16300
int w[M],to[M],ne[M],h[N];
int cnt;
int dist[N],vis[N];
int n,m,be,en;
queue<int>q;
void add( int a,int b,int c){
    w[cnt]=c;to[cnt]=b;ne[cnt]=h[a];h[a]=cnt++;
}
void spfa(){
    q.push(be);
    while(!q.empty()){
        int now=q.front();
        vis[now]=0;//?????
        q.pop();
        for( int i=h[now];i!=-1;i=ne[i]){
            int j=to[i];
            // dist[j]=min(dist[j],dist[now]+w[i]);
            if(dist[j]>dist[now]+w[i]){
                dist[j]=dist[now]+w[i];
                if(vis[j]==0){
                    vis[j]=1;
                    q.push(j);
                }
            }
        }
    }
}
int main(){

    cin>>n>>m>>be>>en;
    memset(h,-1,sizeof(h));
    memset(dist,0x3f,sizeof(dist));
    for( int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }
    dist[be]=0;
    vis[be]=1;
    spfa();
    cout<<dist[en];
    
}

AcWing 1128. 信使 /《信息学奥赛一本通》

#include<bits/stdc++.h>
using namespace std;
#define N 110
#define  M 1010
int w[M],ne[M],to[M],h[N];
int cnt;
int vis[N],dist[N];
queue<int>q;
void add( int a,int b,int c){
    w[cnt]=c,to[cnt]=b,ne[cnt]=h[a],h[a]=cnt++;
}
void spfa(){
    dist[1]=0;
    vis[1]=1;
    q.push(1);
    while(!q.empty()){
        int now=q.front();
        q.pop();
        vis[now]=0;
        for( int i=h[now];i!=-1;i=ne[i]){
            int j=to[i];
            if(dist[j]>dist[now]+w[i]){
                dist[j]=dist[now]+w[i];
                if(vis[j]==0){
                    vis[j]=1;
                    q.push(j);
                }
            }
        }
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    memset(h,-1,sizeof(h));
    memset(dist,0x3f,sizeof(dist));
    for( int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }
    spfa();
    int ans=0;
    for( int i=1;i<=n;i++){
        ans=max(ans,dist[i]);
    }
    if(ans>1e9) cout<<-1;
    else cout<<ans;
}

acwing 1127香甜的黄油 /《信息学奥赛一本通》

#include <bits/stdc++.h>
using namespace std;
#define N 1010
#define M 3010
typedef long long ll;
int n,p,m;
int to[M],h[N],ne[M],w[M];
int cnt=0;
int pos[N];
queue<int >q;
int vis[N];
int dist[N];
void add( int a,int b,int c){
	to[cnt]=b;w[cnt]=c;ne[cnt]=h[a];h[a]=cnt++;
}
void spfa(int be){
    memset(dist,0x3f,sizeof(dist));
	dist[be]=0;
	vis[be]=1;
	q.push(be);
	while(!q.empty()){
		int now=q.front();
		q.pop();
		vis[now]=0;
		for( int i=h[now];i!=-1;i=ne[i]){
			int j=to[i];
			if(dist[now]+w[i]<dist[j]){
				dist[j]=dist[now]+w[i];
				if(vis[j]==0) {
					vis[j]=1;
					q.push(j);
				}
			}
		}
	}
}
int main(){
	cin>>n>>p>>m;
	ll ans=0x7fffffff;
	memset(h,-1,sizeof(h));
	for( int i=1;i<=n;i++){
		int x;
		cin>>x;
		pos[i]=x;
	}
	for( int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		add(a,b,c);
		add(b,a,c);
	}
	for( int i=1;i<=p;i++){
		spfa(i);
		ll sum=0;
		for( int j=1;j<=n;j++){
			sum+=dist[pos[j]];
		}
		ans=min(ans,sum);
	}
	cout<<ans;
} 

acwing 1126/《信息学奥赛一本通》

#include<bits/stdc++.h>
using namespace std;
#define N 2010
#define M 1001000
int n,m; 
int ne[M],to[M],h[N];
double w[M];
int cnt;
int vis[N];
double dist[N];
void add(int a,int b,double c){
    w[cnt]=c;to[cnt]=b;ne[cnt]=h[a];h[a]=cnt++;
}
void dijistra(int be,int en){
    dist[be]=1;
    vis[be]=1;
    int start=be;
    for( int i=0;i<=n;i++){
        double maxx=0;
        for( int j=h[start];j!=-1;j=ne[j]){
            int t=to[j];
            dist[t]=max(dist[start]*w[j],dist[t]);
            // cout<<t<<" "<<dist[t]<<endl;
        }
        for( int j=0;j<=n;j++){
            // cout<<maxx<<" "<<dist[5]<<endl;;
            if(dist[j]>maxx&&vis[j]==0){
                maxx=dist[j];
                start=j;
            }    
        }
        vis[start]=1;
    }
}
int main(){
    cin>>n>>m;
    memset(h,-1,sizeof(h));
    for( int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        double d=(100.0-c)/100.0;
        add(a,b,d);
        add(b,a,d);
    }
    int be,en;
    cin>>be>>en;
    dijistra(be,en);
    printf("%.8lf",100/dist[en]);
}

acwing 920最优乘车
本题中,边的权值都是1,所以可以直接使用bfs找到最短路。
本题的最少换成次数就是最少乘车次数-1
本题中输入不定长,需要使用sstream,而且acwing使用的是vs编译器,不支持fflush(stdin)清空缓存区

#include<bits/stdc++.h>
using namespace std;
#define N 510
int n,m;
int a[510][510];
struct p{
	int step;
	int val;
};
queue<p>q;
int vis[N];
int bfs(){
	q.push((p){0,1});
	vis[1]=1;
	while(!q.empty()){
		p now=q.front();
		q.pop();
		if(now.val==n) return now.step;
		for( int i=1;i<=n;i++){
		 	if(a[now.val][i]==1&&vis[i]==0){
		 		vis[i]=1;
		 		q.push((p){now.step+1,i});
			}
		}
	}
	return -1;
}
int main(){
	cin>>m>>n;
	getchar();
	for( int i=1;i<=m;i++){
		string s;
		getline(cin,s);
		stringstream str(s);
		int p,cnt=0;
		int b[510];
		while(str>>p) {
			b[cnt++]=p;
		}
		for( int j=0;j<cnt;j++){
			for( int t=j+1;t<cnt;t++){
				a[b[j]][b[t]]=1;
			}
		}
	}
	int ans=bfs();
	if(ans==-1) cout<<"NO";
	else cout<<max(0,ans-1)<<endl;这里注意起点和终点重合的情况
}

acwing 903/poj 昂贵的聘礼

#include<bits/stdc++.h>
using namespace std;
#define N 110
int mp[N][N];//存储每个点到另一个点的优惠价格
int w[N];
int pos[N]; 
int m,n;
int vis[N],dist[N];
struct p{
    int h,l;
    int val;
    p(){
        h=0;l=0;
    }
};
queue<p>q;
void spfa(){
	vis[1]=1;
	dist[1]=0;
	p now;
	now.val=1;
	now.h=pos[1];now.l=pos[1];
	q.push(now);
	while(!q.empty()){
		p temp=q.front();
		vis[temp.val]=0;
		q.pop();
		for( int i=1;i<=n;i++){
		    p now=temp;
			if(dist[now.val]+mp[now.val][i]<dist[i]&&mp[now.val][i]!=-1){
			    int sub=max(pos[i],now.h)-min(pos[i],now.l);
			    if(sub>m) continue;
			    else {
			        now.h=max(now.h,pos[i]);
			        now.l=min(now.l,pos[i]);
			    }
				dist[i]=dist[now.val]+mp[now.val][i];
			    now.val=i;
				if(vis[i]==0){
					q.push(now);
					vis[i]=1;
				}
			}
		}	
	}
}
int main(){
	memset(mp,-1,sizeof(mp));
	cin>>m>>n;
	for( int i=1;i<=n;i++){
		int num;
		cin>>w[i]>>pos[i]>>num;
		for( int j=1;j<=num;j++){
			int a,b;
			cin>>a>>b;
			mp[i][a]=b;
		}
	}
	memset(dist,0x3f,sizeof(dist));
	int ans=0x7fffffff;
	spfa();
	for( int i=1;i<=n;i++){
		ans=min(ans,dist[i]+w[i]);
	}
	cout<<ans;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值