题目链接
Bobo has a network of nn nodes and mm arcs. The i i i-th arc goes from the a i a_i ai-th node to the b i b_i bi-th node, with cost c i c_i ci.
Bobo also asks q questions. The ii-th question is specified by two integers u i u_i ui and v i v_i vi, which is to ask the minimum cost to send one unit of flow from the 1-th node to the n-th node, when all the edges have capacity u i v i \frac{u_i}{v_i} viui.
You can refer the wiki page for further information of Minimum-cost Flow.
The input consists of several test cases terminated by end-of-file.
The first line of each test case contains two integers n and m. The i-th of the following m lines contains three integers a i a_i ai, b i b_i bi and c i c_i ci. The next line contains an integer q. The i-th of the last q lines contains two integers u i u_i ui and v i v_i vi.
For each test case, print q fractions (or NaN, if it is impossible to send one unit of flow) which denote the answer.
2 1
1 2 2
1
1 1
2 2
1 2 1
1 2 2
3
1 2
2 3
1 4
2/1
3/2
4/3
NaN
题意可以说是非常非常裸的费用流了,因为一般网络流的题目都要建图,这题直接把图给你了,难点就是 q q q 次查询了,每次给你一个边的容量,让你计算最小费用,每次都跑一遍费用流显然不现实,所以我们先把边的容量置为 1,跑一遍费用流,记录增广路径的花费,后续的每一次查询,给定容量 u v \frac{u}{v} vu,那么我们可以将容量扩大 v v v 倍,那么所有容量都变成了 u u u,流量变成了 v v v,如果最大流小于 v v v,则输出 N a N NaN NaN,最小费用只需要从记录的增广路径中贪心选择即可,注意题目卡了 i n t int int,AC代码如下:
#include
#define INF 0x3f3f3f3f
const int maxn=5e5+10;
const int maxm=5e5+10;
using namespace std;
typedef long long ll;
struct node{
int to, ne, w, cost;
}e[maxm];
int head[maxn], cnt;
int pre[maxn];
int dis[maxn];
bool vis[maxn];
int n, m;
int S, T;
map<ll,ll>mp;
void init(){
cnt = 0;
mp.clear();
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w, int c){
e[cnt] = (node){v, head[u], w, c}; head[u] = cnt++;
e[cnt]= (node){u, head[v], 0, -c,}; head[v] = cnt++;
}
queue<int>q;
int flow[maxn];
bool SPFA(){
while(!q.empty()) q.pop();
memset(dis, INF, sizeof(dis));
memset(vis, false, sizeof(vis));
memset(flow,INF,sizeof(flow));
memset(pre, -1, sizeof(pre));
dis[S] = 0;vis[S] = 1;
q.push(S);
while(!q.empty()){
int u = q.front(); q.pop();
vis[u] = 0;
for(int i = head[u]; i != -1; i = e[i].ne){
int v=e[i].to;
if(dis[v] > dis[u] + e[i].cost && e[i].w){
flow[v]=min(flow[u],e[i].w);
dis[v] = dis[u] + e[i].cost;
pre[v] = i;
if(!vis[v]) vis[v] = 1,q.push(v);
}
}
}
return ~pre[T];
}
void MCMF(int &c, int &f){
f=c=0;
while(SPFA()){
int i=pre[T],d=flow[T];
while(~i){
e[i].w-=d;
e[i^1].w+=d;
i=pre[e[i^1].to];
}
f+=d;c+=d*dis[T];
mp[d*dis[T]]+=d;
}
}
void getMap(){
int u,v,c;
S=1,T=n;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&c);
add(u,v,1,c);
}
}
int main(){
while(~scanf("%d%d",&n,&m)){
init();
getMap();
int cost,flow;
ll u,v,q;
MCMF(cost,flow);
scanf("%lld",&q);
while(q--){
scanf("%lld%lld",&u,&v);
ll x=0,y=v;
if(flow*u<v) printf("NaN\n");
else{
for(auto i:mp){
if(v>i.second*u){
v-=i.second*u;
x+=i.first*u;
}else{
x+=i.first*v/i.second;
break;
}
}
ll r=__gcd(x,y);
printf("%lld/%lld\n",x/r,y/r);
}
}
}
return 0;
}