暴力竟然过了、、利用vector记录每个多边形顶点,明天看别的解法,mark下(据说线段树)
#include<cstdio> #include<vector> using namespace std; vector<int>vt[10005]; int c[10005]; int n,m; int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<10005;i++) vt[i].clear(); for(int i=1;i<=n;i++) vt[0].push_back(i); int l=1; for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); if(a>b) { int tp=a; a=b; b=tp; } for(int j=0;j<l;j++) { int t=0,x,y,d=0; for(int k=0;k<vt[j].size();k++) { if(vt[j][k]==a)d++,x=k; if(vt[j][k]==b)d++,y=k; c[t++]=vt[j][k]; } if(d==2) { for(int w=x;w<=y;w++) vt[l].push_back(vt[j][w]); vt[j].clear(); for(int w=0;w<t;w++) { if(w>x&&w<y) continue; vt[j].push_back(c[w]); } l++; break; } } } int maxn=0; for(int i=0;i<l;i++) { if(maxn<vt[i].size()) maxn=vt[i].size(); } printf("%d\n",maxn); } return 0;}
线段树做法:
#include<cstdio> #include<utility> #include<algorithm> const int MAXN=1<<14; using namespace std; typedef pair < int , int> PII; pair <int,PII> cut[MAXN]; struct segtree { int m,t[4*MAXN]; void init(int l,int r,int i,int n) { m=n; if(l==r) { t[i]=1; return; } int m=(l+r)>>1; init(l,m,2*i,n); init(m+1,r,2*i+1,n); t[i]=t[2*i]+t[2*i+1]; } void del(int l,int r,int a,int b,int i) { if(l==a&&r==b) { t[i]=0; return; } int m=(l+r)>>1; if(m>=b) del(l,m,a,b,2*i); else if(a>m) del(m+1,r,a,b,2*i+1); else { del(l,m,a,m,2*i); del(m+1,r,m+1,b,2*i+1); } t[i]=t[2*i]+t[2*i+1]; } void del(int l,int r) { if(l>r) return; del(1,m,l,r,1); } int sum(int l,int r,int a,int b,int i) { if(t[i]==0||(l==a&&r==b)) return t[i]; int m=(l+r)>>1; if(m>=b) return sum(l,m,a,b,2*i); else if(a>m) return sum(m+1,r,a,b,2*i+1); else { return sum(l,m,a,m,2*i)+sum(m+1,r,m+1,b,2*i+1); } } } seg; int n,m; int main() { while(2==scanf("%d%d",&n,&m)) { seg.init(1,n,1,n); for(int i=0;i<m;i++) { scanf("%d%d",&cut[i].second.first,&cut[i].second.second); if(cut[i].second.first>cut[i].second.second) swap(cut[i].second.first,cut[i].second.second); cut[i].first=cut[i].second.second-cut[i].second.first; if(2*cut[i].first>n) { cut[i].first=n-cut[i].first; swap(cut[i].second.first,cut[i].second.second); } } sort(cut,cut+m); int maxn=-1; for(int i=0;i<m;i++) { if(cut[i].second.second<cut[i].second.first) { maxn=max(maxn,seg.sum(1,n,cut[i].second.first,n,1)+seg.sum(1,n,1,cut[i].second.second,1)); seg.del(cut[i].second.first+1,n); seg.del(1,cut[i].second.second-1); } else { maxn=max(maxn,seg.sum(1,n,cut[i].second.first,cut[i].second.second,1)); seg.del(cut[i].second.first+1,cut[i].second.second-1); } } maxn=max(maxn,seg.sum(1,n,1,n,1)); printf("%d\n",maxn); } return 0; }