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 }
View Code

 

posted @ 2020-02-04 11:04  Blue233333  阅读(68)  评论(0编辑  收藏  举报