Day 48 算法笔记之提高篇(4)10.4 最短路径(剩余习题)

目录

1.Public Bike Management

2.All Roads Lead to Rome




#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;

const int maxv = 510;
const int inf = 1000000000;

int n,m,cmax,sp,numpath=0,g[maxv][maxv],weight[maxv];
int d[maxv],minneed=inf,minremain=inf;
bool vis[maxv] = {false};
vector<int> pre[maxv];
vector<int> temppath,path;

void dijkstra(int s){
	fill(d,d+maxv,inf);
	d[s] = 0;
	for(int i=0;i<n;i++){
		int u=-1,min=inf;
		for(int j=0;j<=n;j++){
			if(vis[j]==false&&d[j]<min){
				u = j;
				min = d[j];
			}
		}
		if(u==-1) return;
		vis[u] = true;
		for(int v=0;v<=n;v++){
			if(vis[v]==false&&g[u][v]!=inf){
				if(d[u]+g[u][v]<d[v]){
					d[v] = d[u]+g[u][v];
					pre[v].clear();
					pre[v].push_back(u);
				}else if(d[u]+g[u][v]==d[v]){
					pre[v].push_back(u);
				}
			}
		}
	}
}

void dfs(int v){
	if(v==0){
		temppath.push_back(v);
		int need=0,remain=0;
		for(int i=temppath.size()-1;i>=0;i--){
			int id = temppath[i];
			if(weight[id]>0){
				remain += weight[id];
			}else{
				if(remain>abs(weight[id])){
					remain -= abs(weight[id]);
				}else{
					need+=abs(weight[id])-remain;
					remain=0;
				}
			}
		}
		if(need<minneed){
			minneed = need;
			minremain = remain;
			path = temppath;
		}else if(need==minneed&&remain<minremain){
			minremain = remain;
			path = temppath;
		}
		temppath.pop_back();
		return;
	}
	temppath.push_back(v);
	for(int i=0;i<pre[v].size();i++){
		dfs(pre[v][i]);
	}
	temppath.pop_back();
	
}

int main(){
	
	scanf("%d%d%d%d",&cmax,&n,&sp,&m);
	int u,v;
	fill(g[0],g[0]+maxv*maxv,inf);
	for(int i=1;i<=n;i++){
		scanf("%d",&weight[i]);
		weight[i] -= cmax/2;
	}
	for(int i=0;i<m;i++){
		scanf("%d%d",&u,&v);
		scanf("%d",&g[u][v]);
		g[v][u] = g[u][v];
	}
	
	dijkstra(0);
	dfs(sp);
	printf("%d ",minneed);
	for(int i=path.size()-1;i>=0;i--){
		printf("%d",path[i]);
		if(i>0) printf("->");
	}
	
	printf(" %d",minremain);
	return 0;
}

2.All Roads Lead to Rome

#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;

const int maxv = 1020;
const int inf = 10000000;

int n,m,k,ds,g[maxv][maxv];
int d[maxv];
bool vis[maxv] = {false};

void dijkstra(int s){
	memset(vis,false,sizeof(vis));
	fill(d,d+maxv,inf);
	
	d[s] = 0;
	for(int i=0;i<n+m;i++){
		int u = -1,min = inf;
		for(int j=1;j<=n+m;j++){
			if(vis[j]==false&&d[j]<min){
				u = j;
				min = d[j];
			}
		}
		if(u==-1) return;
		vis[u] = true;
		for(int v=1;v<n+m;v++){
			if(vis[v]==false&&g[u][v]!=inf){
				if(d[u]+g[u][v]<d[v]){
					d[v] = d[u] +g[u][v];
				}
			}
		}
	}
}

int getid(char str[]){
	int i=0,len=strlen(str),id=0;
	while(i<len){
		if(str[i]!='G'){
			id = id*10+(str[i]-'0');
		}
		i++;
	}
	if(str[0]='G') return n+id;
	else return id;
}


int main(){
	
	scanf("%d%d%d%d",&n,&m,&k,&ds);
	int u,v,w;
	char city1[5],city2[5];
	fill(g[0],g[0]+maxv*maxv,inf);
	for(int i=0;i<k;i++){
		scanf("%s %s %d",city1,city2,&w);
		u = getid(city1);
		v = getid(city2);
		g[v][u] = g[u][v] = w;
	}
	
	double ansdis=-1,ansavg=inf;
	int ansid=-1;
	for(int i=n+1;i<=n+m;i++){
		double mindis=inf,avg=0;
		dijkstra(i);
		for(int j=1;j<=n;j++){
			if(d[j]>ds){
				mindis=-1;
				break;
			}
			if(d[j]<mindis) mindis = d[j];
			avg+=1.0*d[j]/n;
		}
		if(mindis==-1) continue;
		if(mindis>ansdis){
			ansid=i;
			ansdis=mindis;
			ansavg=avg;
		}else if(mindis==ansdis&&avg<ansavg){
			ansid = i;
			ansavg = avg;
		}
	}
	if(ansid==-1) printf("No Solution\n");
	else{
		printf("G%d\n",ansid-n);
		printf("%.lf %.lf\n",ansdis,ansavg);
	}
	
	return 0;
}

おすすめ

転載: blog.csdn.net/aixiaoxiao13/article/details/121639747