博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SGU 303 Great Berland Wall(计算几何判环+最小割)
阅读量:6147 次
发布时间:2019-06-21

本文共 4696 字,大约阅读时间需要 15 分钟。

题目链接:

题意:给出平面上一些线段,已知这些线段只在端点处相交,且这些线段围成了若干封闭图形。每条线段有一个代价。有两个点分别位于两个封闭图形中。选择一些线段将两个点分开且这些线段的代价和最小?

思路:首先,找出所有的环。对于一条线段,每次找它的最左侧的作为下一条。将所有的环编号。然后找出给出的两个点在哪个环里。我用的环绕法判断是不是2PI。以给出的两个点所在环为源点 和汇点,有公共边的两个环连边费用为边的代价。接着跑s到t的最小割也就是最大流。从sDFS一次找到能遍历到的点。最后对于一条边,若其连接的两个点一个是被遍历到一个是未被遍历到则这条边所对应的原来的一条线段就是答案中的一个。

class point{public:    i64 x,y;    point(){}    point(i64 _x,i64 _y)    {        x=_x;        y=_y;    }    void get()    {        RD(x,y);    }    i64 operator*(point a)    {        return x*a.y-y*a.x;    }    point operator-(point a)    {        return point(x-a.x,y-a.y);    }    i64 operator^(point a)    {        return x*a.x+y*a.y;    }    double getAng(point a)    {        return atan2(1.0*(*this*a),((*this)^a)*1.0);    }    void print()    {        printf("(%lld,%lld)",x,y);    }};class node{public:    int u,v,w,next;};const int N=605;map
Map;point a[N],S,T;int n,m,head[N],e,s,t;node edges[N];int getId(point p){ i64 t=(i64)(p.x+10000)*10000+(p.y+10000); if(Map.find(t)!=Map.end()) return Map[t]; return Map[t]=++m;}void Add(int u,int v,int w){ edges[e].u=u; edges[e].v=v; edges[e].w=w; edges[e].next=head[u]; head[u]=e++;}int b[N];i64 area;vector
V[N];i64 cross(int x,int y,int p){ return (a[y]-a[x])*(a[p]-a[x]);}i64 cross(point x,point y,point p){ return (y-x)*(p-x);}void DFS(int x,int id){ b[id]=n; V[n].pb(id); int u=edges[id].u,v=edges[id].v,v1,i,p,k=-1; i64 X,Y,Z; if(u!=x) swap(u,v); for(i=head[v];i!=-1;i=edges[i].next) { v1=edges[i].v; if(v1==u) continue; if(k==-1) { k=i; p=v1; continue; } X=cross(a[u],a[v],a[v1]); Y=cross(a[u],a[v],a[p]); Z=cross(a[v],a[p],a[v1]); if(X>0&&Y<=0||X==0&&Y<0||X*Y>=0&&Z>=0) k=i,p=v1; } area+=a[u]*a[v]; if(k!=-1&&!b[k]) DFS(v,k);}int isInside(point s,vector
V){ int i; point u,v; double sum=0; FOR0(i,SZ(V)) { u=a[edges[V[i]].u]; v=a[edges[V[i]].v]; sum+=(u-s).getAng(v-s); } return fabs(fabs(sum)-2*PI)<1e-5;}struct Node{ int u,v,cap,flow,next,visited,id; Node(){} Node(int _u,int _v,int _cap,int _next,int _id) { u=_u; v=_v; cap=_cap; next=_next; visited=0; id=_id; }};const int INF=1000000000;const int M=100005;int num[M],h[M],curedge[M],pre[M];int queue[M];Node edges1[1200005];int head1[M],e1;void add(int u,int v,int cap,int id){ edges1[e1]=Node(u,v,cap,head1[u],id); head1[u]=e1++; edges1[e1]=Node(v,u,0,head1[v],id); head1[v]=e1++;}void BFS(int s,int t){ memset(num,0,sizeof(num)); memset(h,-1,sizeof(h)); num[0]=1; int front=0,rear=0; h[t]=0; queue[rear++]=t; int u,v,i; while(front!=rear) { u=queue[front++]; front=front%M; for(i=head1[u];i!=-1;i=edges1[i].next) { v=edges1[i].v; if(edges1[i].cap!=0||h[v]!=-1) continue; queue[rear++]=v; rear=rear%M; ++num[h[v]=h[u]+1]; } }}int Maxflow(int s,int t,int n){ int ans=0,i,k,x,d,u; BFS(s,t); for(i=0;i<=n;i++) curedge[i]=head1[i]; num[n]=n;u=s; while(h[u]
edges1[curedge[i]].cap) k=i,d=edges1[curedge[i]].cap; for(i=s;i!=t;i=edges1[curedge[i]].v) { x=curedge[i]; edges1[x].cap-=d; edges1[x^1].cap+=d; } ans+=d;u=k; } for(i=curedge[u];i!=-1;i=edges1[i].next) if(edges1[i].cap>0&&h[u]==h[edges1[i].v]+1) break; if(i!=-1) { curedge[u]=i; pre[edges1[i].v]=u; u=edges1[i].v; } else { if(--num[h[u]]==0) break; curedge[u]=head1[u]; for(x=n,i=head1[u];i!=-1;i=edges1[i].next) if(edges1[i].cap>0&&h[edges1[i].v]
0&&!visit[v]) DFS1(v); }}int main(){ RD(n); int i,j,u,v,w,out; clr(head,-1); FOR0(i,n) { S.get();T.get();RD(w); u=getId(S); v=getId(T); a[u]=S; a[v]=T; Add(u,v,w); Add(v,u,w); } a[0]=point(0,0); n=0; FOR0(i,e) if(!b[i]) { n++;area=0; DFS(edges[i].u,i); if(area<0) out=n; } S.get();T.get(); FOR1(i,n) if(i!=out) { if(isInside(S,V[i])) s=i; if(isInside(T,V[i])) t=i; } clr(head1,-1); for(i=0;i
ans; FOR0(i,e1) { u=edges1[i].u; v=edges1[i].v; if(visit[u]!=visit[v]) ans.pb(edges1[i].id); } sort(ans.begin(),ans.end()); int size=unique(ans.begin(),ans.end())-ans.begin(); PR(size); FOR0(i,size) printf("%d ",ans[i]); puts(""); return 0;}

  

转载地址:http://snmya.baihongyu.com/

你可能感兴趣的文章
c++面向对象的一些问题1 0
查看>>
直播视频流技术名词
查看>>
IOC —— AOP
查看>>
比特币现金将出新招,推动比特币现金使用
查看>>
数据库的这些性能优化,你做了吗?
查看>>
某大型网站迁移总结(完结)
查看>>
部署SSL证书后,网页内容造成页面错误提示的处理办法
查看>>
MS SQLSERVER通用存储过程分页
查看>>
60.使用Azure AI 自定义视觉服务实现物品识别Demo
查看>>
Oracle 冷备份
查看>>
jq漂亮实用的select,select选中后,显示对应内容
查看>>
C 函数sscanf()的用法
查看>>
python模块之hashlib: md5和sha算法
查看>>
解决ros建***能登录不能访问内网远程桌面的问题
查看>>
pfsense锁住自己
查看>>
vsftpd 相关总结
查看>>
售前工程师的成长---一个老员工的经验之谈
查看>>
Get到的优秀博客网址
查看>>
【Git入门之四】操作项目
查看>>
老男孩教育每日一题-第107天-简述你对***的理解,常见的有哪几种?
查看>>