题面
https://www.luogu.org/problem/P2494
题解
#include<cstdio> #include<cstring> #include<iostream> #include<vector> #include<queue> #include<cstdlib> #define N 705 #define M 100050 #define N1M1 42000 #define ri register int #define INF 1000000007.666 using namespace std; int n,m,m1,n1,cnt; int to[M<<1],t[M<<1],s[M<<1]; vector<int> ed[N]; vector<int> dap[N]; double dis[N]; double min(double a,double b) { if(a<b)return a;else return b; } void add_edge(int ca,int cb,int ct,int cs) { ed[ca].push_back(++cnt); to[cnt]=cb; t[cnt]=ct; s[cnt]=cs; } struct initshen { double nt[M<<1]; double f[N]; double dp(int x) { if (f[x]<=INF-1) return f[x]; f[x]=INF-2; for (ri i=0;i<ed[x].size();i++) { int e=ed[x][i]; if (e%2==0) continue; if (dp(to[e])+nt[e]<f[x]) f[x]=dp(to[e])+nt[e]; } return f[x]; } void solve(vector<int> cur,double lb,double rb) { double mid=(lb+rb)/2; if (rb-lb<1e-3) { for (ri i=0,l=cur.size();i<l;i++) dis[cur[i]]=mid; return; } for (ri i=1;i<=n;i++) f[i]=INF; f[n]=0; for (ri i=1;i<=cnt;i+=2) nt[i]=t[i]-mid*s[i]; vector<int> curL,curR; for (ri i=0,l=cur.size();i<l;i++) if (dp(cur[i])>=0) curR.push_back(cur[i]); else curL.push_back(cur[i]); if (curL.size()) solve(curL,lb,mid); if (curR.size()) solve(curR,mid,rb); } void work() { vector<int> cur; for (ri i=1;i<=n1;i++) cur.push_back(i); solve(cur,0.0,11.0); return; } } wym; struct DIN { #define S 0 #define T n1+m1+1 vector<int> ed[N1M1]; int d[N1M1],cur[N1M1]; vector<double> w; vector<int> to; void add_edge(int a,int b,double ww) { w.push_back(ww); to.push_back(b); ed[a].push_back(to.size()-1); return; } void makeGraph() { for (ri i=1;i<=n1;i++) { if (i%2==1) { add_edge(0,i,dis[i]); add_edge(i,0,0); } else { add_edge(i,T,dis[i]); add_edge(T,i,0); } } for (ri i=1;i<=n1;i++) { if (i%2==1) { for (ri j=0,l=dap[i].size();j<l;j++) { int y=dap[i][j]; add_edge(i,n1+y,INF); add_edge(n1+y,i,0); } } else { for (ri j=0,l=dap[i].size();j<l;j++) { int y=dap[i][j]; add_edge(n1+y,i,INF); add_edge(i,n1+y,0); } } } } bool bfs() { memset(d,0x3f,sizeof(d)); d[0]=1; queue<int> q; q.push(0); while (!q.empty()) { int x=q.front(); q.pop(); for (ri i=0,l=ed[x].size();i<l;i++) { int e=ed[x][i]; if (d[to[e]]>d[x]+1 && w[e]-1e-5>0) { d[to[e]]=d[x]+1; q.push(to[e]); } } } return d[T]<N1M1; } double dfs(int x,double limit) { if (x==T) return limit; double tot=0; for (ri &i=cur[x];i<ed[x].size();i++) { int e=ed[x][i]; if (d[x]+1==d[to[e]] && w[e]-1e-5>0) { double f=dfs(to[e],min(limit,w[e])); if (f-1e-5<=0) continue; w[e]-=f; w[1^e]+=f; tot+=f; limit-=f; if (limit-1e-5<=0) return tot; } } return tot; } double dinic() { double ret=0; while (bfs()) { memset(cur,0,sizeof(cur)); ret+=dfs(S,INF); } return ret; } void work() { makeGraph(); double ans=dinic(); if (ans<100) printf("%.1lf\n",ans); else puts("-1"); } } wls; int main(){ scanf("%d %d",&n,&m); int ca,cb,ct,cs,u,v; cnt=-1; for (ri i=1;i<=m;i++) { scanf("%d %d %d %d",&ca,&cb,&ct,&cs); add_edge(ca,cb,ct,cs); add_edge(cb,ca,ct,cs); } scanf("%d %d",&m1,&n1); for (ri i=1;i<=m1;i++) { scanf("%d %d",&u,&v); dap[u].push_back(i); dap[v].push_back(i); } wym.work(); wls.work(); }