我是真的没想到这题能最短路
全往费用流上想去了
还是学得太少
这题其实一看就不是费用流
费用流要求在最大流前提下的最小费用
而这道题不一定能够最大流
题意
一个图,每条边有限制 f f f和代价 c c c, m a x i m i z e ( min i { f i } ∑ c i ) maximize(\frac{\min_i\{f_i\}}{\sum c_i}) maximize(∑cimini{fi})
题解
将
c
c
c视为边权,求最短路
考虑
f
f
f的影响
发现可以枚举
f
f
f,因为它小 (随便欺负人家小是不对的😐)
O
(
n
2
log
n
)
O(n^2\log n)
O(n2logn)
不能二分 f f f的原因:答案不关于 f f f单调
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0,f=1;char ch=0;
while (!isdigit(ch) && ch!='-') ch=getchar();
if (ch=='-') ch=getchar(),f=-1;
while (isdigit(ch))
i=(i<<1)+(i<<3)+ch-48, ch=getchar();
return i*f;
}
#define st first
#define nd second
#define mp make_pair
const int N=1e3+5;
int n,m,maxf,ans,dis[N];
int tot,first[N],nxt[N<<1],aim[N<<1],c[N<<1],f[N<<1];
void ljb(int u,int v,int cc,int ff){
++tot;
nxt[tot]=first[u];
first[u]=tot;
aim[tot]=v;
c[tot]=cc;
f[tot]=ff;
return;
}
void Dijkstra(int lim){
priority_queue<pair<int,int> >q;
memset(dis,0x3f,sizeof dis);
dis[1]=0;
q.push(mp(dis[1],1));
while(!q.empty()){
int u=q.top().nd;q.pop();
for(int e=first[u];e;e=nxt[e]){
if(f[e]<lim) continue;
int v=aim[e];
if(dis[v]>dis[u]+c[e]){
dis[v]=dis[u]+c[e];
q.push(mp(dis[v],v));
}
}
}
return;
}
int main(){
n=in,m=in;
for(int i=1;i<=m;++i){
int u=in,v=in,cc=in,ff=in;
ljb(u,v,cc,ff);
ljb(v,u,cc,ff);
if(maxf<ff) maxf=ff;
}
for(int i=1;i<=maxf;++i){
Dijkstra(i);
ans=max(ans,(int)floor(1.0*i/dis[n]*1e6));
}
printf("%d\n",ans);
return 0;
}
就这就这就这???