1 条题解

  • 1
    @ 2022-8-16 22:09:39
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<map>
    #include<string>
    #include<deque>
    #include<cmath>
    #define MAXN 10010
    #define MAXM 200010
    #define eps (1e-7)
    #define MAX (1<<30)//一大堆宏定义
    using namespace std;
    
    map<string,int> name;//直接用map存节点编号
    int n,m,k,cost,limit,s,t;
    int top=0,gas_stack[MAXN],id[MAXN][12];
    double length[MAXN];
    bool gas[MAXN];
    
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    
    struct SPFA{
    	int c,head[MAXM];
    	double path[MAXM];
    	bool vis[MAXM];
    	SPFA(){c=1;}
    	struct Graph{
    		int next,to;
    		double w;
    	}a[MAXM<<2];
    	inline int relax(int u,int v,double w){
    		if(path[v]>path[u]+w){
    			path[v]=path[u]+w;
    			return 1;
    		}
    		return 0;
    	}
    	inline void add(int u,int v,double w){
    		a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
    	}
    	void spfa(int s){
    	    int u,v;
    	    deque<int> q;
    	    for(int i=1;i<=n*(k+1);i++){path[i]=MAX;vis[i]=false;}
    	    path[s]=0;
    	    vis[s]=true;
    	    q.push_back(s);
    	    while(!q.empty()){
    	        u=q.front();
    	        q.pop_front();
    	        vis[u]=false;
    	        for(int i=head[u];i;i=a[i].next){
    	            v=a[i].to;
    	            if(relax(u,v,a[i].w)&&!vis[v]){
    	                vis[v]=true;
    	                if(!q.empty()){
    	                    if(path[v]>path[q.front()])q.push_back(v);
    	                    else q.push_front(v);
    	                }
    	                else q.push_back(v);
    	            }
    	        }
    	    }
    	}
    }one,two;//旧图和新图
    
    inline void add_edge(int u,int v,int w){//建立分层图
    	if(fabs(length[v])>eps)for(int j=0;j<k;j++)one.add(id[u][j],id[v][j+1],w+length[v]);
    	else for(int j=0;j<=k;j++)one.add(id[u][j],id[v][j],w);
    }
    void work(){//求解
    	double ans=MAX;
    	two.spfa(s);
    	for(int i=0;i<=k;i++)ans=min(ans,two.path[t+i*n]);
    	printf("%.3lf\n",ans);
    }
    void init(){//读入+预处理+建分层图
    	string x;
    	int u,v;
    	double w;
    	n=read();m=read();k=read();limit=read();cost=read();
        
    	for(int i=0;i<=k;i++)
    	for(int j=1;j<=n;j++)
    	id[j][i]=j+i*n;
        
    	for(int i=1;i<=n;i++){
    		cin>>x;
    		name[x]=i;
    		int red=read(),green=read();
    		if(x=="start")s=i;
    		else if(x=="end")t=i;
    		if(x.find("gas")!=string::npos)gas[i]=true;
    		if(red)length[i]=1.00*red*red/(double)(2.00*(red+green));
    		else length[i]=0;
    	}
        
    	for(int i=1;i<=m;i++){
    		cin>>x;u=name[x];
    		cin>>x;v=name[x];
    		cin>>x;w=read();
    		add_edge(u,v,w);
    		add_edge(v,u,w);
    	}
        
    	gas[s]=gas[t]=true;
    	for(int i=1;i<=n;i++)if(gas[i])gas_stack[++top]=i;
        
    	for(int i=1;i<=top;i++){//旧图与新图的转换
    		one.spfa(gas_stack[i]);
    		for(int j=1;j<=top;j++){
    			if(i==j)continue;
    			w=(gas_stack[j]!=s&&gas_stack[j]!=t)?cost:0;
    			for(int l=0;l<=k;l++)
    			if(one.path[id[gas_stack[j]][l]]<=limit)
    			for(int p=0;p+l<=k;p++)
    			two.add(id[gas_stack[i]][p],id[gas_stack[j]][p+l],one.path[id[gas_stack[j]][l]]+w);
    		}
    	}
    }
    int main(){//主函数So easy!
    	init();
    	work();
        return 0;
    }
    
    • 1

    信息

    ID
    236
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    4
    上传者