分数规划,将边权改造;
第一次被卡精度,mmp
#include#include #include #include #define maxx 1000000000#define ecp 1e-5using namespace std;struct {int y,next,hh;double flow;}e[10000];int lin[10000],len=0,re[10000];int f=0;int hh[10000];int read(){ int k;cin>>k;return k;}void init(int x,int y,double fo,int id){ e[++len].next=lin[x];e[len].y=y;e[len].flow=fo;lin[x]=len,re[len]=len+1;e[len].hh=id; e[++len].next=lin[y];e[len].y=x;e[len].flow=fo;lin[y]=len;re[len]=len-1;e[len].hh=id; return ;}struct pp{int a,b;}sum[10000];bool aaa(pp q,pp w){return q.a>w.a||q.a==w.a&&q.b 0&&level[y]==-1){level[y]=level[x]+1;q[++tail]=y;} } } return level[ed]!=-1;}double makeflow(int x,double flow){ if(x==ed)return flow; double axx=0,d=0; for(int i=lin[x];i&&axx 0) { if(d=makeflow(y,min(flow-axx,e[i].flow))) { axx+=d; e[i].flow-=d; e[re[i]].flow+=d; } } } if(axx==0)level[x]=-1; return axx;}double dinic(){ double ans=0; double d; while(makelevel()) while(d=makeflow(st,maxx)) ans+=d; return ans;}double build(double k){ double ansx=0; len=0; memset(re,0,sizeof(re)); memset(lin,0,sizeof(lin)); memset(e,0,sizeof(e)); for(int i=1;i<=m;i++) { double fo=1.0*c[i]-k; if(fo<0){ansx+=fo;if(f==1){ans[++top]=i;}} else {init(a[i],b[i],fo,i);} } return ansx;}void work1(){ double left=0,right=1e10; double mid; while(left+1e-9 0)left=mid; else right=mid; } zxc=left; return ;}void rebuild(){ for(int i=1;i<=len;i+=2)e[i].flow=e[re[i]].flow=1.0*(e[re[i]].flow+e[i].flow)/2;}void work2(){ f=1; build(zxc); xxx=dinic(); rebuild(); double j=dinic(); for(int i=1;i<=len;i++) { sum[i].a=e[i].flow; sum[i].b=i; } sort(sum+1,sum+len+1,aaa); for(int i=1;i<=len;i++) { rebuild(); int t=sum[i].b; if(k[t]==1)continue; k[t]=1; k[re[t]]=1; double w=dinic()+e[t].flow; if(w+ecp>=xxx&&w-ecp<=xxx){xxx-=e[t].flow;ans[++top]=e[t].hh;} else k[t]=0,k[re[t]]=0; } printf("%d\n",top); sort(ans+1,ans+top+1); for(int i=1;i<=top;i++) { cout< <<' '; } cout<