我发现平面图转对偶图经常和最小割在一起。
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 }