ZOJ2676 Network Wars
https://zoj.pintia.cn/problem-sets/91827364500/problems/91827366175
分数规划+最小割。
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 using namespace std; 6 #define LL long long 7 8 int n,m; 9 #define maxn 111 10 #define maxm 444*4 11 struct PreEdge{int x,y,v;}e[maxm]; 12 struct Edge{int to,next,id; double cap,flow;}; 13 struct Net 14 { 15 int n,le,first[maxn],s,t; Edge edge[maxm]; 16 void clear(int N) {n=N; le=2; memset(first,0,sizeof(first));} 17 void in(int x,int y,double c,int id) 18 {Edge &e=edge[le]; e.to=y; e.cap=c; e.flow=0; e.id=id; e.next=first[x]; first[x]=le++;} 19 void insert(int x,int y,double c,int id) {in(x,y,c,id); in(y,x,0,id);} 20 int cur[maxn]; bool vis[maxn]; int dis[maxn],que[maxn],head,tail; 21 bool bfs() 22 { 23 memset(dis,0,sizeof(dis)); 24 head=0; tail=1; que[0]=s; dis[s]=1; 25 while (head!=tail) 26 { 27 int x=que[head++]; 28 for (int i=first[x];i;i=edge[i].next) 29 { 30 Edge &e=edge[i]; if (dis[e.to] || e.cap-e.flow<1e-9) continue; 31 dis[e.to]=dis[x]+1; 32 que[tail++]=e.to; 33 } 34 } 35 return dis[t]>0; 36 } 37 double dfs(int x,double a) 38 { 39 if (x==t || a<1e-9) return a; 40 double flow=0,f; 41 for (int &i=cur[x];i;i=edge[i].next) 42 { 43 Edge &e=edge[i]; 44 if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>1e-9) 45 { 46 flow+=f; 47 e.flow+=f; 48 a-=f; 49 edge[i^1].flow-=f; 50 if (a<1e-9) break; 51 } 52 } 53 return flow; 54 } 55 double Dinic(int S,int T) 56 { 57 s=S; t=T; 58 double ans=0; 59 while (bfs()) 60 { 61 for (int i=1;i<=n;i++) cur[i]=first[i]; 62 ans+=dfs(s,1e8); 63 } 64 return ans; 65 } 66 void dfs2(int x) 67 { 68 vis[x]=1; 69 for (int i=first[x];i;i=edge[i].next) 70 { 71 Edge &e=edge[i]; 72 if (!vis[e.to] && e.cap-e.flow>1e-9) dfs2(e.to); 73 } 74 } 75 }g; 76 77 double eps=1e-6; int ans[maxm],lans; 78 int main() 79 { 80 while (~scanf("%d%d",&n,&m)) 81 { 82 double L=0,R=0; 83 for (int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v),R=max(R,(double)e[i].v); 84 85 while (R-L>eps) 86 { 87 double mid=(L+R)/2.; 88 g.clear(n); 89 double cal=0; 90 for (int i=1;i<=m;i++) 91 if (e[i].v>mid) g.insert(e[i].x,e[i].y,e[i].v-mid,i),g.insert(e[i].y,e[i].x,e[i].v-mid,i); 92 else cal+=e[i].v-mid; 93 if (g.Dinic(1,n)+cal>1e-9) L=mid+eps; 94 else R=mid; 95 } 96 97 g.clear(n); 98 lans=0; 99 for (int i=1;i<=m;i++) if (e[i].v<L+eps) ans[++lans]=i; 100 else g.insert(e[i].x,e[i].y,e[i].v-L,i),g.insert(e[i].y,e[i].x,e[i].v-L,i); 101 g.Dinic(1,n); 102 memset(g.vis,0,sizeof(g.vis)); 103 g.dfs2(1); 104 for (int i=1;i<=n;i++) if (g.vis[i]) 105 for (int j=g.first[i];j;j=g.edge[j].next) 106 if (!g.vis[g.edge[j].to] && g.edge[j].cap>1e-9 107 && g.edge[j].cap-g.edge[j].flow<1e-9) ans[++lans]=g.edge[j].id; 108 sort(ans+1,ans+1+lans); lans=unique(ans+1,ans+1+lans)-ans-1; 109 printf("%d\n",lans); 110 for (int i=1;i<lans;i++) printf("%d ",ans[i]); 111 printf("%d\n\n",ans[lans]); 112 } 113 return 0; 114 }