题解
由于所有边的容量相同,所以可以得到一个性质,的流量在图中形成了k条1-n的路径,每多u的流量多形成一条路径(可能会导致原路径改变,但是只会在
到
时发生改变),这u的流量所用的花费是相同的,所以考虑u和v的倍数关系,预处理出u为1,v从1到100的花费,然后询问时直接求出对应的花费
代码
#include <bits/stdc++.h> using namespace std; #define paii pair<int,int> #define fr first #define sc second typedef long long ll; const int N=2e5+5; const int p=1e9+7; ll qpow(ll a,ll n){ll res=1;while(n){if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;} struct ZKW_SPFA{ #define maxn 201 #define maxe 5005 const ll INF=1e18; ll dis[maxn],vis[maxn],head[maxn],tot; ll n,Cost=0,Flow=0; struct Edge{ll v,cap,cost,nxt;}g[maxe<<1]; void init(ll _n){tot=Cost=Flow=0;memset(head,-1,sizeof(head));n=_n;} void add(ll u,ll v,ll cap,ll cost){ g[tot]={v,cap,cost,head[u]};head[u]=tot++; } void addedge(ll u,ll v,ll cap,ll cost){ add(u,v,cap,cost);add(v,u,0,-cost); } bool spfa(ll S,ll T){ for(ll i=0;i<=n;i++) vis[i]=0,dis[i]=INF; deque<ll>Q;Q.push_back(T);dis[T]=0;vis[T]=1; while(!Q.empty()){ ll u=Q.front();Q.pop_front(); for(ll i=head[u],v;~i;i=g[i].nxt) if(g[i^1].cap&&dis[v=g[i].v]>dis[u]+g[i^1].cost){ dis[v]=dis[u]+g[i^1].cost; if(!vis[v]){ vis[v]=1; if(!Q.empty()&&dis[v]<dis[Q.front()]) Q.push_front(v); else Q.push_back(v); //SLF??? } } vis[u]=0; } return dis[S]<INF; } ll dfs(ll S,ll T,ll flow){ if(S==T){vis[T]=1;return flow;} ll used=0,res;vis[S]=1; for(ll i=head[S],v;~i;i=g[i].nxt) if(!vis[v=g[i].v]&&g[i].cap&&dis[S]-g[i].cost==dis[v]){ res=dfs(v,T,min(g[i].cap,flow-used)); if(res) Cost+=res*g[i].cost,g[i].cap-=res,g[i^1].cap+=res,used+=res; if(used==flow)break; } return used; } void solve(ll S,ll T){ while(spfa(S,T)){ vis[T]=1; while(vis[T]) memset(vis,0,sizeof vis),Flow+=dfs(S,T,INF); } } //?zkw.init(n),?zkw.addedge(),?zkw.solve(S,T) //????zkw.Flow??kw.Cost }zkw; ll ans[105]; ll x[105],y[105],z[105]; void work() { int n,m; while(~scanf("%d%d",&n,&m)){ zkw.init(n+2); for(int i=1;i<=m;i++){ scanf("%lld%lld%lld",&x[i],&y[i],&z[i]); } int limit=0; for(int i=1;i<=101;i++){ zkw.init(n+2); zkw.addedge(n+1,1,i,0); for(int j=1;j<=m;j++){ zkw.addedge(x[j],y[j],1,z[j]); } zkw.solve(n+1,n); ans[i]=zkw.Cost; if(zkw.Flow!=i){ limit=i-1;break; } } int q; scanf("%d",&q); while(q--){ ll u,v; scanf("%lld%lld",&u,&v); if(u*limit<v){ printf("NaN\n");continue; } ll sum=ans[v/u]*u; ll tmp=v%u; sum+=(ans[v/u+1]-ans[v/u])*tmp; ll tmp1=__gcd(sum,v); sum/=tmp1; v/=tmp1; printf("%lld/%lld\n",sum,v); } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int T=1; //scanf("%d",&T); //cin>>T; while(T--){ work(); } }