codeforces 223E 計算幾何 圖論 網路流思想

來源:互聯網
上載者:User

http://codeforces.com/problemset/problem/223/E

題意: 給你一堆座標點,然後告訴你他們之間的串連情況,所有的邊都是雙向的,並且圖是連通的。邊數,點數都是10w層級

然後開始詢問,每個詢問是輸入圖中某個多邊形的所有頂點,然後問你這個多邊形內部一共有幾個點(包括邊界上的點)

題解在這裡http://codeforces.com/blog/entry/5301

看完後就懂了,關鍵就是利用流的思想,當選定某個簡單多邊形的時候,內部的點數就等於流進去的流量和減去流出來的流量和,反正就是流量差,怎麼定義很自由

統計的時候不能暴力

利用座標的極角序處理出一個首碼和就可以很快得到答案

具體見代碼

關於多邊形的內部究竟在哪一側還是搞了我很長時間,太糾結了

#include<cmath>#include<cstring>#include<cstdlib>#include<cstdio>#include<algorithm>#include<map>#include<set>#include<vector>using namespace std;#define MP make_pair#define PB push_back const int maxn  =  100010;const double inf = 1e10;struct Point {double x,y;Point(){};Point(double sx,double sy) : x(sx),y(sy){}}p[maxn];double operator / (const Point &b,const Point &a) {return atan2(b.y-a.y,b.x-a.x);}bool operator  <  (const Point &a,const Point &b){if(a.x!=b.x) return a.x<b.x;return a.y<b.y;}inline double cross(double x1,double y1,double x2,double y2){return x1*y2-x2*y1;}inline double chacha(Point s,Point a,Point b){    return cross(a.x-s.x,a.y-s.y,b.x-s.x,b.y-s.y);}struct Edge{double ang;int to;Edge(){}Edge(double a,int t):ang(a),to(t){};bool operator < (const Edge &cmp) const{return ang<cmp.ang;}};vector<Edge> edge[maxn];map<pair<int,int>,int> sum,flow;int all[maxn];int n,m;inline void add_edge(int u,int v){Edge k;    k.to=v;k.ang=p[v]/p[u];edge[u].PB(k);flow[MP(u,v)]=0;}bool vis[maxn];int dfs(int u,int f){    vis[u]=true;int cnt=1;for(vector<Edge>::iterator it=edge[u].begin();it!=edge[u].end();it++){int v=it->to;if(!vis[v])cnt+=dfs(v,u);}if(f){flow[MP(f,u)]+=cnt;flow[MP(u,f)]-=cnt;}return cnt;}int ss[maxn],tt[maxn];vector<int> cut;inline int gao(int a,int b,int c){double bb = p[b]/p[a],cc = p[c]/p[a];if(bb < cc) {return sum[MP(a,c)] - sum[MP(a,b)] - flow[MP(a,c)];}else {return all[a] + sum[MP(a,c)] - sum[MP(a,b)] - flow[MP(a,c)];}}void solve(){int ans=0,num=cut.size(),i;double s=0;p[0]=Point(0,0);for(i=0;i<num;i++)s+=chacha(p[0],p[cut[i==0 ? num-1 : i-1]],p[cut[i]]);if(s>0) reverse(cut.begin(),cut.end());//變成順時針for(i=0;i<num;i++){     int tmp=gao( cut[i], cut[(i==0 ? num-1 : i-1)] , cut[(i+1)%num] ) ;         ans+=tmp;}printf("%d\n",ans+num);}int main(){int u,v,q,k,i,j,leftmost,T,cir,c;scanf("%d%d",&n,&m);    for(i=1;i<=m;i++)  scanf("%d%d",&ss[i],&tt[i]);for(i=1;i<=n;i++)  scanf("%lf%lf",&p[i].x,&p[i].y);for(i=1;i<=m;i++){add_edge(ss[i],tt[i]);add_edge(tt[i],ss[i]);}p[T=n+1]=Point(-inf,0);for(leftmost=i=1;i<=n;i++) if(p[i]<p[leftmost])   leftmost=i;add_edge(T,leftmost);add_edge(leftmost,T);dfs(T,0);    for(i=1;i<=n+1;i++) sort(edge[i].begin(),edge[i].end());for(i=1;i<=n+1;i++){int pre=i;sum[MP(i,i)] = 0;for(vector<Edge>::iterator it=edge[i].begin();it!=edge[i].end();it++){all[i]+=flow[MP(i,it->to)];sum[MP(i,it->to)] = sum[MP(i,pre)] + flow[MP(i,it->to)];pre=it->to;}}scanf("%d",&q);while(q--){scanf("%d",&k);cut.clear();for(i=1;i<=k;i++) scanf("%d",&c),cut.PB(c);solve();}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.