码迷,mamicode.com
首页 > 其他好文 > 详细

[校内训练2021_03_04]C平面图转对偶图2

时间:2021-03-05 13:00:48      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:return   type   open   with   wait   set   else   clu   str   

我发现平面图转对偶图经常和最小割在一起。
技术图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long int ll;
  4 typedef long double ld;
  5 typedef pair<int,int> pii;
  6 const int maxn=5E3+5;
  7 const ld pi=acos(-1);
  8 const ll inf=1E12;
  9 int n;
 10 struct pt
 11 {
 12     ll x,y;
 13     pt(ll a=0,ll b=0):x(a),y(b){}
 14     pt operator+(const pt&A){return pt(x+A.x,y+A.y);}
 15     pt operator-(const pt&A){return pt(x-A.x,y-A.y);}
 16     ll operator*(const pt&A){return x*A.y-y*A.x;}
 17     bool operator<(const pt&A)const
 18     {
 19         return x==A.x?y<A.y:x<A.x;
 20     }
 21     bool operator==(const pt&A)const
 22     {
 23         return x==A.x&&y==A.y;
 24     }
 25     inline ld len()
 26     {
 27         return sqrt(x*x+y*y);
 28     }
 29 }p[maxn];
 30 int tot;
 31 map<pt,int>where;
 32 struct line
 33 {
 34     ll x1,y1,x2,y2,w;
 35 }a[maxn];
 36 int size,head[maxn];
 37 struct edge
 38 {
 39     int to,next,id;
 40     ll w;
 41 }E[maxn*2];
 42 int cnt,bel[maxn];
 43 bool vis[maxn*2];
 44 ll gap[1005][1005];
 45 inline void add(int u,int v,ll w,int id)
 46 {
 47     E[++size].to=v;
 48     E[size].next=head[u];
 49     E[size].w=w;
 50     E[size].id=id;
 51     head[u]=size;
 52 }
 53 inline void clear()
 54 {
 55     memset(head,0,sizeof(head));
 56     memset(E,0,sizeof(E));
 57     memset(vis,0,sizeof(vis));
 58     memset(gap,0,sizeof(gap));
 59     memset(bel,0,sizeof(bel));
 60     where.clear();
 61     cnt=size=tot=0;
 62 }
 63 inline ld getRa(pt x,pt y)
 64 {
 65     if(x.x==y.x&&x.y==y.y)
 66         return 0;
 67     ld mo=(ld)(x.x*y.x+x.y*y.y)/x.len()/y.len();
 68     ld ra=acos(mo);
 69     if((x*y)>=0)
 70         return ra;
 71     return 2*pi-ra;
 72 }
 73 void dfs(int u,int last,int id,int c)
 74 {
 75     if(vis[id])
 76         return;
 77     bel[id]=c;
 78     vis[id]=1;
 79     int nextU=0,nextId=0,gg=0;
 80     pt O=p[last]-p[u];
 81     for(int i=head[u];i;i=E[i].next)
 82     {
 83         int v=E[i].to;
 84         if(nextU==0)
 85             nextU=v,nextId=E[i].id,gg=i;
 86         else
 87         {
 88             ld x=getRa(O,p[v]-p[u]);
 89             ld y=getRa(O,p[nextU]-p[u]);// !!!!!!!
 90             if(x>y)
 91                 nextU=v,nextId=E[i].id,gg=i;
 92         }
 93     }
 94     dfs(nextU,u,nextId,c);
 95 }
 96 ll ans;
 97 namespace FLOW
 98 {
 99     int S,T;
100     int size=1,head[maxn];
101     struct edge
102     {
103         int to,next;
104         ll w,g;
105     }E[maxn*2];
106     inline void addE(int u,int v,ll w)
107     {
108         E[++size].to=v;
109         E[size].next=head[u];
110         E[size].w=w;
111         E[size].g=w;
112         head[u]=size;
113     }
114     inline void add(int u,int v,ll w)
115     {
116         addE(u,v,w);
117         addE(v,u,0);
118     }
119     int dfn[maxn];
120     inline bool bfs()
121     {
122         queue<int>Q;
123         Q.push(S);
124         for(int i=S;i<=T;++i)
125             dfn[i]=-1;
126         dfn[S]=0;
127         while(!Q.empty())
128         {
129             int u=Q.front();
130             Q.pop();
131             for(int i=head[u];i;i=E[i].next)
132             {
133                 int v=E[i].to;
134                 if(dfn[v]!=-1||E[i].w==0)
135                     continue;
136                 dfn[v]=dfn[u]+1;
137                 Q.push(v);
138             }
139         }
140         return dfn[T]!=-1;
141     }
142     ll dfs(int u,ll up)
143     {
144         if(u==T)
145             return up;
146         ll s=0;
147         for(int i=head[u];i;i=E[i].next)
148         {
149             int v=E[i].to;
150             if(dfn[v]!=dfn[u]+1||E[i].w==0)
151                 continue;
152             ll g=dfs(v,min(up-s,E[i].w));
153             s+=g;
154             E[i].w-=g;
155             E[i^1].w+=g;
156             if(g==0)
157                 dfn[v]=-1;
158             if(s==up)
159                 break;
160         }
161         return s;
162     }
163     bool vis[maxn];
164     inline void init()
165     {
166         memset(head,0,sizeof(head));
167         memset(E,0,sizeof(E));
168         S=0,T=cnt+1;
169         for(int i=1;i<=cnt;++i)
170             for(int j=i+1;j<=cnt;++j)
171                 if(gap[i][j])
172                     add(i,j,gap[i][j]),add(j,i,gap[j][i]);
173         for(int i=1;i<=cnt;++i)
174             add(S,i,0);
175         for(int i=1;i<=cnt;++i)
176             add(i,T,0);
177     }
178     inline void bend(int s,int t)
179     {
180         for(int u=1;u<=cnt;++u)
181             for(int i=head[u];i;i=E[i].next)
182                 E[i].w=E[i].g;
183         for(int i=head[S];i;i=E[i].next)
184         {
185             if(E[i].to!=s)
186                 E[i].w=E[i^1].w=0;
187             else
188                 E[i].w=inf,E[i^1].w=0;
189         }
190         for(int i=head[T];i;i=E[i].next)
191         {
192             if(E[i].to!=t)
193                 E[i].w=E[i^1].w=0;
194             else
195                 E[i^1].w=inf,E[i].w=0;
196         }
197     }
198     vector<int>solve(int s,int t)
199     {
200         size=1;
201         bend(s,t);
202         while(bfs())
203             ans+=dfs(S,inf);
204         queue<int>Q;
205         for(int i=S;i<=T;++i)
206             vis[i]=0;
207         Q.push(S);
208         vis[S]=1;
209         vector<int>wait;
210         while(!Q.empty())
211         {
212             int u=Q.front();
213             Q.pop();
214             for(int i=head[u];i;i=E[i].next)
215             {
216                 int v=E[i].to;
217                 if(E[i].w==0||vis[v])
218                     continue;
219                 Q.push(v);
220                 vis[v]=1;
221             }
222         }
223         for(int i=1;i<=cnt;++i)
224             if(vis[i])
225                 wait.push_back(i);
226         return wait;
227     }
228 }
229 int TI,visD[maxn];
230 void cut(vector<int>D)
231 {
232     if(D.size()==1)
233         return;
234     vector<int>DD=FLOW::solve(D[0],D[1]);
235     ++TI;
236     for(int i=0;i<DD.size();++i)
237         visD[DD[i]]=TI;
238     vector<int>DL,DR;
239     for(int i=0;i<D.size();++i)
240         if(visD[D[i]]==TI)
241             DL.push_back(D[i]);
242         else
243             DR.push_back(D[i]);
244     cut(DL),cut(DR);
245 }
246 inline void solve()
247 {
248     clear();
249     cin>>n;
250     for(int i=1;i<=n;++i)
251     {
252         cin>>a[i].x1>>a[i].y1>>a[i].x2>>a[i].y2>>a[i].w;
253         pt A=pt(a[i].x1,a[i].y1);
254         if(!where[A])
255         {
256             where[A]=++tot;
257             p[tot]=A;
258         }
259         pt B=pt(a[i].x2,a[i].y2);
260         if(!where[B])
261         {
262             where[B]=++tot;
263             p[tot]=B;
264         }
265         add(where[A],where[B],a[i].w,i*2);
266         add(where[B],where[A],a[i].w,i*2+1);
267     }
268     for(int u=1;u<=tot;++u)
269         for(int i=head[u];i;i=E[i].next)
270             if(!vis[E[i].id])
271             {
272                 ++cnt;
273                 dfs(E[i].to,u,E[i].id,cnt);
274             }
275     for(int u=1;u<=tot;++u)
276         for(int i=head[u];i;i=E[i].next)
277         {
278             int x=bel[E[i].id],y=bel[E[i].id^1];
279             gap[x][y]+=E[i].w;
280         }
281     vector<int>D;
282     for(int i=1;i<=cnt;++i)
283         D.push_back(i);
284     ans=0;
285     FLOW::init();
286     cut(D);
287     cout<<ans<<endl;
288 }
289 int main()
290 {
291     freopen("fence.in","r",stdin);
292     freopen("fence.out","w",stdout);
293     ios::sync_with_stdio(false);
294     int T;
295     cin>>T;
296     while(T--)
297         solve();
298     return 0;
299 }
View Code

 

[校内训练2021_03_04]C平面图转对偶图2

标签:return   type   open   with   wait   set   else   clu   str   

原文地址:https://www.cnblogs.com/GreenDuck/p/14480740.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!