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));
26         {
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  阅读(80)  评论(0编辑  收藏  举报