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!\n");system("pause");for (;;);exit(0);} } return *p1++; } inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';} 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; }