題目是按通過量做的,所以題號可能不太對。
1.Vacation
這種問題一定不能思考的太複雜,不要把自己繞進去。
我們就簡單的將其分成兩類:
(1) 前面沒車堵我。
(2) 前面全部都堵我。
對於第一種情況,沒車堵我,那麼顯然就是s[0]/v[0]。
重點關注第二種情況,前面所有的車都堵我。
思考了五秒鐘以後我們發現,前面所有的車都堵我是啥意思,就是第一輛車最慢唄。
那麼答案是什麼呢?就是(s[n]+sum[n])/v[n]。因爲n是第一輛車。
這樣我們就可以觀察出來,我的速度是受別人的限制的。
所以我們枚舉每一輛前面的車,看看它會不會堵我就行了。
複雜度O(n)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
double l[maxn],s[maxn],v[maxn];
double sum[maxn];
int n;
int main()
{
while(~scanf("%d",&n))
{
for(int i=0;i<=n;i++) scanf("%lf",l+i);
for(int i=0;i<=n;i++) scanf("%lf",s+i);
for(int i=0;i<=n;i++) scanf("%lf",v+i);
double ans = s[0]/v[0];
sum[0] = 0;
for(int i=1;i<=n;i++)
{
sum[i] = sum[i-1] + l[i];
ans = max(ans,(s[i]+sum[i])/v[i]);
}
printf("%.6lf\n",ans);
}
return 0;
}
2.Path
很明顯先求一個最短路,然後在最短路的邊上求最小割就完事了。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e4+7;
struct node
{
int to;
int cost;
};
vector<node> V[maxn];
int n,m;
int x[maxn],y[maxn],z[maxn];
ll dis[maxn];
struct edge
{
int to;
ll cap;
int rev;
};
vector<edge> G[maxn];
int depth[maxn],arc[maxn];
void add_edge(int from,int to,ll cost)
{
G[from].push_back((edge){to,cost,G[to].size()});
G[to].push_back((edge){from,0,G[from].size()-1});
}
void bfs(int s)
{
queue<int> q;
memset(depth,-1,sizeof(depth));
depth[s] = 0;
q.push(s);
while(!q.empty())
{
int v = q.front();
q.pop();
for(int i=0;i<G[v].size();i++)
{
edge &e = G[v][i];
if(e.cap>0 && depth[e.to]<0)
{
depth[e.to] = depth[v]+1;
q.push(e.to);
}
}
}
}
ll dfs(int v,int t,ll f)
{
if(v==t) return f;
for(int &i=arc[v];i<G[v].size();i++)
{
edge &e = G[v][i];
if(e.cap>0 && depth[e.to]==depth[v]+1)
{
ll d = dfs(e.to,t,min(f,e.cap));
if(d>0)
{
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
ll dinic(int s,int t)
{
ll flow = 0;
while(true)
{
bfs(s);
if(depth[t]<0) return flow;
memset(arc,0,sizeof(arc));
ll f;
while((f=dfs(s,t,INF))>0)
{
flow += f;
}
}
}
void dijkstra(int s)
{
struct edge
{
int now;
int cost;
bool operator<(const edge &rhs)const
{
return cost>rhs.cost;
}
};
memset(dis,INF,sizeof(dis));
dis[s] = 0;
priority_queue<edge> q;
q.push({s,dis[s]});
while(!q.empty())
{
edge tmp = q.top();
q.pop();
for(int i=0;i<V[tmp.now].size();i++)
{
int v = V[tmp.now][i].to;
if(dis[v]>dis[tmp.now]+V[tmp.now][i].cost)
{
dis[v] = dis[tmp.now] + V[tmp.now][i].cost;
q.push({v,dis[v]});
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(G,0,sizeof(G));
memset(V,0,sizeof(V));
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",x+i,y+i,z+i);
V[x[i]].push_back({y[i],z[i]});
}
dijkstra(1);
for(int i=1;i<=n;i++)
{
for(int j=0;j<V[i].size();j++)
{
int v = V[i][j].to;
if(dis[v]==dis[i]+V[i][j].cost) add_edge(i,v,V[i][j].cost);
}
}
printf("%d\n",dinic(1,n));
}
return 0;
}