当前位置: 代码迷 >> 综合 >> zoj-3792-Romantic Value-最小割+数值转化
  详细解决方案

zoj-3792-Romantic Value-最小割+数值转化

热度:53   发布时间:2023-12-19 10:31:21.0

如果不需要求边的个数的话,就是一个裸的最小割问题。

求边的个数就用边的权值记录一下。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include<queue>
using namespace std;
#define INF 99999999
#define LL long long
const LL maxn =55;
const LL maxm =4400;
const LL oo = (LL)1<<37;
struct Arclist
{LL cnt, head[maxn], dis[maxn];LL cur[maxn], pre[maxn], gap[maxn], aug[maxn];struct node{LL u, v, w, next;}edge[maxm];void init(){cnt = 0;memset(head,-1,sizeof(head));}void add(LL u, LL v, LL w){// cout<<u<<" "<<v<<" "<<w<<endl;edge[cnt].u = u;edge[cnt].v = v;edge[cnt].w = w;edge[cnt].next = head[u];head[u] = cnt++;edge[cnt].u = v;edge[cnt].v = u;edge[cnt].w = 0;edge[cnt].next = head[v];head[v] = cnt++;}LL sap(LL s, LL e, LL n){LL max_flow = 0, u = s;LL mindis;for(LL i = 0; i <= n; i++){cur[i] = head[i];dis[i] = 0;gap[i] = 0;}aug[s] = oo;pre[s] = -1;gap[0] = n;while(dis[s]<n){bool flag = false;if(u==e){max_flow += aug[e];for(LL v = pre[e]; v != -1; v = pre[v]){LL id = cur[v];edge[id].w -= aug[e];edge[id^1].w += aug[e];aug[v] -= aug[e];if(edge[id].w==0) u = v;}}for(LL id = cur[u]; id != -1; id = edge[id].next){LL v = edge[id].v;if(edge[id].w>0 && dis[u]==dis[v]+1){flag = true;pre[v] = u;cur[u] = id;aug[v] = std::min(aug[u], edge[id].w);u = v;break;}}if(flag==false){if(--gap[dis[u]]==0) break;mindis = n;cur[u] = head[u];for(LL id = head[u]; id != -1; id = edge[id].next){LL v = edge[id].v;if(edge[id].w>0 && dis[v]<mindis){mindis = dis[v];cur[u] = id;}}dis[u] = mindis+1;++gap[dis[u]];if(u!=s) u = pre[u];}}return max_flow;}
}G;
int main()
{LL m,n,u,v,w,T,st,ed;scanf("%lld",&T);while(T--){scanf("%lld%lld%lld%lld",&n,&m,&st,&ed);G.init();LL all=0;while(m--){scanf("%lld%lld%lld",&u,&v,&w);G.add(v,u,w*1000+1);G.add(u,v,w*1000+1);all+=w;}LL w=G.sap(st,ed,n);// cout<<w<<endl;if(w==0)cout<<"Inf"<<endl;else{double x,y;if(w%1000==0){y=1000;w=w-1000;}else y=w%1000;x=all-w/1000;printf("%.2f\n",1.0*x/y);}}return 0;
}