这种题目让最小值最大,一般就是二分答案。TC的题目总是不那么明显。我一开始认为二分是错的。但是虽然航班出发时间被分成一段一段的,但是等的时间少总能坐上等的时间长能做的航班,大不了多等一会儿。那么就是二分答案加最短路了。
#include <bits/stdc++.h>
#define maxn 1009
using namespace std;
typedef long long LL;
const LL INF=1e17;
char S[100009];
bool inq[maxn];
LL d[maxn];
int n,mx;
struct Edge
{
int v,f,t,p;
Edge(int _v,int _f,int _t,int _p)
{
v=_v;f=_f;t=_t;p=_p;
}
};
vector<Edge>G[maxn];
LL solve(LL cur,LL f,LL p)
{
if(cur<=f)
return f-cur;
else
{
cur%=p;
f%=p;
if(cur<=f)
return f-cur;
else
return f-cur+p;
}
}
bool spfa(LL mid)
{
for(int i=1;i<=n;i++) d[i]=INF;
queue<int>Q;
d[1]=0;
Q.push(1);
while(!Q.empty())
{
int u=Q.front();Q.pop();
inq[u]=0;
for(int i=0;i<(int)G[u].size();i++)
{
int v=G[u][i].v;
LL t=d[u];
if(u==1)
t++;
else
t+=mid;
LL T=solve(t,G[u][i].f,G[u][i].p);
//printf("%d %lld\n",u,t+T);
if(G[u][i].t+T+t>mx)
continue;
if(d[v]>t+G[u][i].t+T)
{
d[v]=t+G[u][i].t+T;
if(!inq[v])
{
inq[v]=1;
Q.push(v);
}
}
}
}
return d[n]<=mx;
}
class TheAirTripDivOne
{
public:int find(int N, vector <string> flights, int time)
{
n=N;
mx=time;
int len=0;
for(int i=0;i<(int)flights.size();i++)
for(int j=0;j<(int)flights[i].length();j++)
S[len++]=flights[i][j];
char *p=strtok(S," ");
while(p)
{
int last=0,cur=0,a,b,f,t,P;
for(;p[cur]!=',';cur++);
p[cur]=0;a=atoi(p+last);p[cur]=',';last=++cur;
for(;p[cur]!=',';cur++);
p[cur]=0;b=atoi(p+last);p[cur]=',';last=++cur;
for(;p[cur]!=',';cur++);
p[cur]=0;f=atoi(p+last);p[cur]=',';last=++cur;
for(;p[cur]!=',';cur++);
p[cur]=0;t=atoi(p+last);p[cur]=',';last=++cur;
P=atoi(p+last);
G[a].push_back(Edge(b,f,t,P));
//printf("%d %d %d %d %d\n",a,b,f,t,P);
p=strtok(NULL," ");
}
LL L=1,R=1e9;
if(!spfa(L))
return -1;
while(L<R)
{
LL M=(L+R+1)>>1;
if(spfa(M))
L=M;
else
R=M-1;
}
return L;
}
};