• BZOJ3245: 最快路线 拆点dijkstra


    150个点,500种速度,乘起来大概8e4个点,3e4的边

    其他题解写的基本都是spfa,想想dij也能做,还挺快

    #include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>                    
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip> 
    #include<bitset>
    using namespace std;         //
    
    #define ll long long  
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++) 
    #define sqr(a) (a)*(a)
    #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
    ll qp(ll a,ll b,ll mod){
    	ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
    }
    struct DOT{int x;int y;};
    const int dx[4]={0,0,-1,1};
    const int dy[4]={1,-1,0,0};
    const int inf=0x3f3f3f3f;  
    const ll mod=1e9+7;
    const int maxn=2e2+5;       //---------------maxn---------------//
    
    /******************************************************/
    namespace fastIO{  
        #define BUF_SIZE 100000  
        #define OUT_SIZE 100000  
        #define ll long long  
        //fread->read  
        bool IOerror=0;  
        inline char nc(){  
            static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;  
            if (p1==pend){  
                p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);  
            if (pend==p1){IOerror=1;return -1;}  
            //{printf("IO error!
    ");system("pause");for (;;);exit(0);}  
        }  
        return *p1++;  
    }  
    inline bool blank(char ch){return ch==' '||ch=='
    '||ch=='
    '||ch=='	';}  
    inline void read(int &x){  
        bool sign=0; char ch=nc(); x=0;  
        for (;blank(ch);ch=nc());  
        if (IOerror)return;  
        if (ch=='-')sign=1,ch=nc();  
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';  
        if (sign)x=-x;  
    }  
    inline void read(ll &x){  
        bool sign=0; char ch=nc(); x=0;  
        for (;blank(ch);ch=nc());  
        if (IOerror)return;  
        if (ch=='-')sign=1,ch=nc();  
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';  
        if (sign)x=-x;  
    }  
    inline void read(double &x){  
        bool sign=0; char ch=nc(); x=0;  
        for (;blank(ch);ch=nc());  
        if (IOerror)return;  
        if (ch=='-')sign=1,ch=nc();  
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';  
        if (ch=='.'){  
            double tmp=1; ch=nc();  
            for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');  
        }  
        if (sign)x=-x;  
    }  
    inline void read(char *s){  
        char ch=nc();  
        for (;blank(ch);ch=nc());  
        if (IOerror)return;  
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;  
        *s=0;  
    }  
    inline void read(char &c){  
        for (c=nc();blank(c);c=nc());  
        if (IOerror){c=-1;return;}  
    } 
    #undef OUT_SIZE  
    #undef BUF_SIZE  
    }; using namespace fastIO;
    /*****************************************************/
    
    
    //n 150,v 500,l 500
    
    int n,m,D;
    
    double d[maxn][550];	//到i点速度为j的最小时间
    pair<int,int> from[maxn][550];	//来源
    
    int head[maxn],tot;
    struct EDGE{
    	int a,b,v,l;
    	int nxt;
    }edges[maxn*maxn];
    void addedge(int a,int b,int v,int l){
    	edges[++tot]=(EDGE){a,b,v,l,head[a]};
    	head[a]=tot;
    }
    
    struct sed{
    	int u;int v;double t;
    	friend bool operator <(sed a,sed b){return a.t>b.t;}};
    priority_queue<sed>Q;
    
    bool vis[maxn][550];
    void dij(){
    	memset(d,127,sizeof d);
    	Q.push((sed){0,70,0});
    	d[0][70]=0;
    	
    	while(!Q.empty()){
    		sed now=Q.top();Q.pop();
    		int x=now.u,vx=now.v;double t=now.t;
    		if(vis[x][vx])continue;
    		vis[x][vx]=1;
    
    		for(int i=head[x];i;i=edges[i].nxt){
    			int y=edges[i].b,vy=edges[i].v,l=edges[i].l;
    			if(vy && d[x][vx]+(double)l/vy < d[y][vy]){
    				d[y][vy]=d[x][vx]+(double)l/vy;
    				from[y][vy]=make_pair(x,vx);
    				Q.push((sed){y,vy,d[y][vy]});
    			}
    			if(!vy && d[x][vx]+(double)l/vx<d[y][vx]){
    				d[y][vx]=d[x][vx]+(double)l/vx;
    				from[y][vx]=make_pair(x,vx);
    				Q.push((sed){y,vx,d[y][vx]});
    			}
    		}
    	}
    }
    
    void print(int x,int vx){
    	if(x)print(from[x][vx].first,from[x][vx].second);
    	printf("%d",x);
    	if(x!=D)printf(" ");
    }
    
    int main(){
    	read(n);read(m);read(D);
    	for(int i=1;i<=m;i++){
    		int a,b,v,l;
    		read(a);read(b);read(v);read(l);
    		addedge(a,b,v,l);
    	}
    	dij();
    	int ans=0;
    	for(int i=1;i<=500;i++){
    		if(d[D][i]<d[D][ans])ans=i;
    	}
    	print(D,ans);
    	return 0;
    }
    


  • 相关阅读:
    Android入门第六篇之ListView (一)
    mysql触发器的作用及语法
    查询记录时rs.previous()的使用
    Microsoft Visual C++ Runtime Library Runtime Error的解决的方法
    Ubuntu中编译链接Opencv应用的简便方式
    24点经典算法
    CMS系统简介(从简介到使用)
    编程学习资源
    Django是什么
    Thinkphp中的自动验证
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611201.html
Copyright © 2020-2023  润新知