Topic: Given a plane graph, the minimum tree diagram of dual graphs is obtained.
This question TM Test me two times!! Two times!! I took two times the 60 points of MST!
The world you win you force me to learn Zhu Liu algorithm 233
#include <cmath> #include <vector> #include <cstdio> #include <cstring> #include <iostream > #include <algorithm> #define M 3030#define INF 0x3f3f3f3fusing namespace std;struct point{int x, y; Point () {}point (int _,int __): X (_), Y (__) {}friend istream& operator >> (IStream &_,point &p) {scanf ("%d %d ", &p.x,&p.y); return _;} Friend point operator-(const point &p1,const point &p2) {return point (P1.X-P2.X,P1.Y-P2.Y);} Friend Double Arctan2 (const point &p) {return atan2 (p.y,p.x);}} Points[m];struct list{list *another;int to,len,belong;double Alpha; List () {}list (int _,int __,double ___): Another (0x0), to (_), Len (__), belong (0), alpha (___) {}};int n,m,cnt=1;vector< list*> a[m];bool Compare (const list *x,const list *y) {return X->alpha < Y->alpha;} void Add (int x,int y,int t1,int T2) {if (!T1) t1=inf;if (!t2) T2=inf; Point P=points[y]-points[x]; List *temp1=new list (Y,t1,arctan2 (p)); List *temp2=new list (x,t2,arctan2 (0,0)-p); teMp1->another=temp2;temp2->another=temp1;a[x].push_back (TEMP1); A[y].push_back (TEMP2);} void DFS (int x,list *from,int aim) {from->belong=cnt;if (X==aim) return; Vector<list*>::iterator It=lower_ Bound (A[x].begin (), A[x].end (), From->another,compare), It++;if (It==a[x].end ()) It=a[x].begin ();D FS ((*it) To,*it,aim);} namespace Dual_graph{struct edge{int X,y,z;edge () {}edge (int _,int __,int ___): X (_), Y (__), Z (___) {}}edges[100100];int n , m;void Add (int x,int y,int z) {++m;edges[m].x=x;edges[m].y=y;edges[m].z=z;} int Dmst () {static int f[m],from[m],v[m],t;static bool Deleted[m];int i,j,re=0;while (1) {memset (f,0x3f,sizeof f); memset (from,0,sizeof from), for (i=1;i<=m;i++) if (f[edges[i].y]>edges[i].z) {f[edges[i].y]=edges[i].z;from[edges[i] . y]=edges[i].x;} for (i=2;i<=n;i++) if (!deleted[i]) if (f[i]==inf) Return-1;memset (v,0,sizeof v), for (i=2;i<=n;i++) if (!deleted[i ] {for (++t,j=i;j!=1&&!v[j];j=from[j]) v[j]=t;if (v[j]==t) break;} if (i==n+1) {for (i=2;i<=n;i++) if (!deleted[i]) re+=f[i]; return re;} memset (V,0,sizeof v); i=j;do{i=from[i];re+=f[i];v[i]=true;deleted[i]=true;} while (i!=j);d eleted[j]=false;int cnt=0;for (i=1;i<=m;i++) {if (!v[edges[i].x]&&!v[edges[i].y]) edges[++ Cnt]=edges[i];else if (v[edges[i].x]&&v[edges[i].y]) Continue;else if (v[edges[i].x]) Edges[++cnt]=edge (J, EDGES[I].Y,EDGES[I].Z); Elseedges[++cnt]=edge (Edges[i].x,j,edges[i].z-f[edges[i].y]);} m=cnt;}}} int main () {//freopen ("square.in", "R", stdin);//freopen ("Square.out", "w", stdout); int i,x,y,t1,t2;cin>>n> >m;for (i=1;i<=n;i++) cin>>points[i];for (i=1;i<=m;i++) {scanf ("%d%d%d%d", &x,&y,&t1, &T2); ADD (X,Y,T1,T2);} for (i=1;i<=n;i++) sort (A[i].begin (), A[i].end (), Compare); for (x=1;x<=n;x++) {Vector<list*>::iterator it ; for (It=a[x].begin (); It!=a[x].end (); it++) if (! ( *it)->belong) ++cnt,dfs ((*it)->to,*it,x);} for (x=1;x<=n;x++) {Vector<list*>::iterator it;for (It=a[x].begin (); It!=a[x].end (); it++) if ((*it)->len! =inf) Dual_graph::add ((*it)->another-> belong, (*it)->belong, (*it)->len);} Dual_graph::n=cnt;for (i=2;i<=cnt;i++) Dual_graph::add (1,i,0x1010101); Cout<<dual_graph::D MST ()- 0x1010101<<endl;return 0;}
Bzoj 2960 Cross-plane dual graph + Zhu Liu algorithm