我发现平面图转对偶图经常和最小割在一起。

HDU5518

  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     ld mo=(ld)(x.x*y.x+x.y*y.y)/x.len()/y.len();
 66     ld ra=acos(min((ld)1,max((ld)-1,mo)));
 67     if((x*y)>=0)
 68         return ra;
 69     return 2*pi-ra;
 70 }
 71 void dfs(int u,int last,int id,int c)
 72 {
 73     if(vis[id])
 74         return;
 75     bel[id]=c;
 76     vis[id]=1;
 77     int nextU=0,nextId=0,gg=0;
 78     pt O=p[last]-p[u];
 79     for(int i=head[u];i;i=E[i].next)
 80     {
 81         int v=E[i].to;
 82         if(nextU==0)
 83             nextU=v,nextId=E[i].id,gg=i;
 84         else
 85         {
 86             ld x=getRa(O,p[v]-p[u]);
 87             ld y=getRa(O,p[nextU]-p[u]);// !!!!!!!
 88             if(x>y)
 89                 nextU=v,nextId=E[i].id,gg=i;
 90         }
 91     }
 92     dfs(nextU,u,nextId,c);
 93 }
 94 ll ans;
 95 namespace FLOW
 96 {
 97     int S,T;
 98     int size=1,head[maxn];
 99     struct edge
100     {
101         int to,next;
102         ll w,g;
103     }E[maxn*2];
104     inline void addE(int u,int v,ll w)
105     {
106         E[++size].to=v;
107         E[size].next=head[u];
108         E[size].w=w;
109         E[size].g=w;
110         head[u]=size;
111     }
112     inline void add(int u,int v,ll w)
113     {
114         addE(u,v,w);
115         addE(v,u,0);
116     }
117     int dfn[maxn];
118     inline bool bfs()
119     {
120         queue<int>Q;
121         Q.push(S);
122         for(int i=S;i<=T;++i)
123             dfn[i]=-1;
124         dfn[S]=0;
125         while(!Q.empty())
126         {
127             int u=Q.front();
128             Q.pop();
129             for(int i=head[u];i;i=E[i].next)
130             {
131                 int v=E[i].to;
132                 if(dfn[v]!=-1||E[i].w==0)
133                     continue;
134                 dfn[v]=dfn[u]+1;
135                 Q.push(v);
136             }
137         }
138         return dfn[T]!=-1;
139     }
140     ll dfs(int u,ll up)
141     {
142         if(u==T)
143             return up;
144         ll s=0;
145         for(int i=head[u];i;i=E[i].next)
146         {
147             int v=E[i].to;
148             if(dfn[v]!=dfn[u]+1||E[i].w==0)
149                 continue;
150             ll g=dfs(v,min(up-s,E[i].w));
151             s+=g;
152             E[i].w-=g;
153             E[i^1].w+=g;
154             if(g==0)
155                 dfn[v]=-1;
156             if(s==up)
157                 break;
158         }
159         return s;
160     }
161     bool vis[maxn];
162     inline void init()
163     {
164         memset(head,0,sizeof(head));
165         memset(E,0,sizeof(E));
166         S=0,T=cnt+1;
167         for(int i=1;i<=cnt;++i)
168             for(int j=i+1;j<=cnt;++j)
169                 if(gap[i][j])
170                     add(i,j,gap[i][j]),add(j,i,gap[j][i]);
171         for(int i=1;i<=cnt;++i)
172             add(S,i,0);
173         for(int i=1;i<=cnt;++i)
174             add(i,T,0);
175     }
176     inline void bend(int s,int t)
177     {
178         for(int u=1;u<=cnt;++u)
179             for(int i=head[u];i;i=E[i].next)
180                 E[i].w=E[i].g;
181         for(int i=head[S];i;i=E[i].next)
182         {
183             if(E[i].to!=s)
184                 E[i].w=E[i^1].w=0;
185             else
186                 E[i].w=inf,E[i^1].w=0;
187         }
188         for(int i=head[T];i;i=E[i].next)
189         {
190             if(E[i].to!=t)
191                 E[i].w=E[i^1].w=0;
192             else
193                 E[i^1].w=inf,E[i].w=0;
194         }
195     }
196     vector<int>solve(int s,int t)
197     {
198         size=1;
199         bend(s,t);
200         while(bfs())
201             ans+=dfs(S,inf);
202         queue<int>Q;
203         for(int i=S;i<=T;++i)
204             vis[i]=0;
205         Q.push(S);
206         vis[S]=1;
207         vector<int>wait;
208         while(!Q.empty())
209         {
210             int u=Q.front();
211             Q.pop();
212             for(int i=head[u];i;i=E[i].next)
213             {
214                 int v=E[i].to;
215                 if(E[i].w==0||vis[v])
216                     continue;
217                 Q.push(v);
218                 vis[v]=1;
219             }
220         }
221         for(int i=1;i<=cnt;++i)
222             if(vis[i])
223                 wait.push_back(i);
224         return wait;
225     }
226 }
227 int TI,visD[maxn];
228 void cut(vector<int>D)
229 {
230     if(D.size()==1)
231         return;
232     ll last=ans;
233     vector<int>DD=FLOW::solve(D[0],D[1]);
234     ++TI;
235     for(int i=0;i<DD.size();++i)
236         visD[DD[i]]=TI;
237     vector<int>DL,DR;
238     for(int i=0;i<D.size();++i)
239         if(visD[D[i]]==TI)
240             DL.push_back(D[i]);
241         else
242             DR.push_back(D[i]);
243     cut(DL),cut(DR);
244 }
245 inline void solve(int T)
246 {
247     clear();
248     cin>>n;
249     for(int i=1;i<=n;++i)
250     {
251         cin>>a[i].x1>>a[i].y1>>a[i].x2>>a[i].y2>>a[i].w;
252         pt A=pt(a[i].x1,a[i].y1);
253         if(!where[A])
254         {
255             where[A]=++tot;
256             p[tot]=A;
257         }
258         pt B=pt(a[i].x2,a[i].y2);
259         if(!where[B])
260         {
261             where[B]=++tot;
262             p[tot]=B;
263         }
264         add(where[A],where[B],a[i].w,i*2);
265         add(where[B],where[A],a[i].w,i*2+1);
266     }
267     for(int u=1;u<=tot;++u)
268         for(int i=head[u];i;i=E[i].next)
269             if(!vis[E[i].id])
270             {
271                 ++cnt;
272                 dfs(E[i].to,u,E[i].id,cnt);
273             }
274     for(int u=1;u<=tot;++u)
275         for(int i=head[u];i;i=E[i].next)
276         {
277             int x=bel[E[i].id],y=bel[E[i].id^1];
278             gap[x][y]+=E[i].w;
279         }
280     vector<int>D;
281 //    for(int i=1;i<=cnt;++i,cout<<endl)
282 //        for(int j=1;j<=cnt;++j)
283 //            cout<<gap[i][j]<<" ";cout<<endl;
284     for(int i=1;i<=cnt;++i)
285         D.push_back(i);
286     ans=0;
287     FLOW::init();
288     cut(D);
289     cout<<"Case #"<<T<<": "<<ans<<endl;
290 }
291 int main()
292 {
293 //    freopen("fence10.in","r",stdin);
294     ios::sync_with_stdio(false);
295     int T;
296     cin>>T;
297     for(int i=1;i<=T;++i)
298         solve(i);
299     return 0;
300 }
View Code

 

 posted on 2021-03-04 15:50  GreenDuck  阅读(93)  评论(0编辑  收藏  举报