其他分享
首页 > 其他分享> > L2-001 紧急救援

L2-001 紧急救援

作者:互联网

L2-001 紧急救援

这道题感觉就是dijstra模板题做了小改动,需要处理所有最短路径,然后记录所有路径和点权和最大的那条,我的处理比较直观(bushi,蠢),比较高明的做法:
我们没必要记录所有最短路经的信息,只需要记录点权最大的那条,但遇到路径长度相等的时候要记录到该点最短路径的条数,在发现相同最短路径的时候更新点权最大的路径

被卡住的地方:当发现更短路径的时候,要直接更新点权最大的路径信息,因为点权最大的路径是从最短路径中选的

rubbish code:

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<stack>
#include<vector>
#define LOCAL
using namespace std;
typedef long long int ll;
/*
题目要求从所有最短路径中选取召集的救援队最多的那条
然后输出最短路径的条数,最多救援队数量,以及 该路径途经城市(包括起始)
具体思路:
 用djstra来搞,记录每个点的pre,查路径倒着查 
*/
int read(){
    int s=0,f=1,c=getchar();
    while (c<'0' || c>'9') { if (c=='-') f=-1; c=getchar();}
    while (c>='0' && c<='9') {s=(s<<3)+(s<<1)+c-'0';c=getchar();}
    return s*f;
}
const int maxn=505;
const int INF=255000;
int dis[maxn][maxn];
int num[maxn];
bool mark[maxn]={0};
vector<int> pre[maxn];
int mm[maxn]; 
int mpre[maxn];//记录到该点的最短路径中救援队最多的那条的前置点(题目中已经说了最优解唯一) 
int n,m,s,d;
void djstra(){
	int stk[n+5];
	int top=0;
	mark[s]=1;
	while (1){
		int mind=INF;
		int flag=0;
		for (int i=0;i<n;++i){
			if (mark[i]) continue;
			flag=1;
			if (dis[s][i]<mind ){
				mind=dis[s][i];
				top=0;
				stk[top++]=i;
			}
			else if (dis[s][i]==mind) stk[top++]=i;
		}
		for (int i=0;i<top;++i){
			mark[stk[i]]=1;
//			cout<<stk[i]<<endl;
		}
		if (flag==0) break;	
		for (int i=0;i<n;++i){
			if (mark[i]) continue;
			for (int j=0;j<top;++j){
//				cout<<stk[j]<<endl;
//				dis[s][i]=min(dis[s][i],dis[s][stk[j]]+dis[stk[j]][i]);
				if (dis[s][i]>dis[s][stk[j]]+dis[stk[j]][i]){
					dis[s][i]=dis[s][stk[j]]+dis[stk[j]][i];
					pre[i].clear();
					pre[i].push_back(stk[j]);
//					if (mm[i]<mm[stk[j]]+num[i]){
					mm[i]=mm[stk[j]]+num[i];
					mpre[i]=stk[j];
//					}
				}
				else if (dis[s][i]==dis[s][stk[j]]+dis[stk[j]][i]){
//					cout<<stk[j]<<endl;
					if (mm[i]<mm[stk[j]]+num[i]){
						mm[i]=mm[stk[j]]+num[i];
						mpre[i]=stk[j];
					}
					pre[i].push_back(stk[j]);
				}
			}
		}
//    cout<<__LINE__<<endl;
		top=0;
	}
}

int dfs(int p){
	if (p==s) return 1;
	int sum=0,len=(int)pre[p].size();
	for (int i=0;i<len;++i){
//		cout<<pre[p][i]<<endl;
		sum+=dfs(pre[p][i]);
	}
	return sum;
}
		
				

int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif
    n=read(),m=read(),s=read(),d=read();
    for (int i=0;i<n;++i){
    	pre[i].push_back(s);
    	mpre[i]=s;
    	num[i]=read();
    	mm[i]=i==s?num[s]:(num[s]+num[i]);
    	for (int j=i+1;j<n;++j) {
    		dis[i][j]=dis[j][i]=INF;
    	}
    }
//    cout<<__LINE__<<endl;
    for (int i=0;i<m;++i){
    	int u=read(),v=read(),w=read();
    	dis[u][v]=min(dis[u][v],w);
    	dis[v][u]=dis[u][v];
//    cout<<__LINE__<<endl;
    }
    djstra();
//    for (int i=0;i<n;++i){
//    	for (int j=0;j<(int)pre[i].size();++j){
//    		cout<<pre[i][j]<<" ";
//    	}
//    	cout<<endl;
//    }
    int res=dfs(d);
    printf("%d %d\n",res,mm[d]);
//	int cont=0;
    int pp=d;
    stack<int> tmp;
	while (pp!=s){
//		cont++;
//		printf("%d ",pp);
		tmp.push(pp);
		pp=mpre[pp];
	}
//	printf("%d %d\n",cont,mm[d]);
	printf("%d",s);
	while (!tmp.empty()){
		int t=tmp.top();
		tmp.pop();
		printf(" %d",t);
	}

    return 0;
}

标签:tmp,救援,int,点权,路径,stk,001,L2,include
来源: https://www.cnblogs.com/DarrenLU/p/16066252.html