最小生成树+最短路裸题?
二分+最短路裸题?
还是归为卡常题吧
别看了,没卡过去
#include<bits/stdc++.h>
#define LEN 2000000
#define INF 1000000000000000000
using namespace std;
inline int getint(){
int x=0,p=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')p=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<3)+(x<<1)+(c^'0');
c=getchar();
}
return x*p;
}
inline void putint(long long x){
if(x<0){
x=-x;
putchar('-');
}
static int buf[30];
int tot=0;
do{
buf[tot++]=x%10;
x/=10;
}while(x);
while(tot)putchar(buf[--tot]+'0');
}
int n,m;
struct road{
int e,nxt,t;
long long len;
}r[LEN*2];
int tot=1,first[LEN];
inline void creat(int a,int b,int t,int c){
r[++tot].t=t;
r[tot].len=c;
r[tot].len*=t;
r[tot].e=b;
r[tot].nxt=first[a];
first[a]=tot;
}
bool vis[LEN];
bool check(int x,int s,int t){
for(int i=1;i<=n;++i){
vis[i]=0;
}
vis[s]=1;
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=first[u];i;i=r[i].nxt){
int v=r[i].e;
if(r[i].t>x)continue;
if(vis[v])continue;
if(v==t)return true;
vis[v]=1;
q.push(v);
}
}
return false;
}
long long dis[LEN];
void dijkstra(int x,int s,int t){
for(int i=1;i<=n;++i){
vis[i]=0;
dis[i]=INF;
}
dis[s]=0;
typedef pair<long long,int> pii;
priority_queue<pii,vector<pii>,greater<pii> >q;
q.push(make_pair(0,s));
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u])continue;
vis[u]=1;
if(u==t)break;
for(int i=first[u];i;i=r[i].nxt){
int v=r[i].e;
if(r[i].t>x)continue;
if(dis[v]>dis[u]+r[i].len){
dis[v]=dis[u]+r[i].len;
q.push(make_pair(dis[v],v));
}
}
}
}
int main(){
n=getint(),m=getint();
for(int i=1;i<=m;++i){
int a=getint(),b=getint(),t=getint(),c=getint();
creat(a,b,t,c);
creat(b,a,t,c);
}
int s,t;
s=getint(),t=getint();
int l=0,r=10000,ans1=0;
while(l<=r){
int mid=l+r>>1;
if(check(mid,s,t)){
ans1=mid;
r=mid-1;
}
else{
l=mid+1;
}
}
putint(ans1),putchar(' ');
dijkstra(ans1,s,t);
putint(dis[t]);
return 0;
}