1.最小圆覆盖
#include<bits/stdc++.h> #define il inline #define D double #define _(d) while(d(isdigit(ch=getchar()))) using namespace std; const int N=5e5+5;struct node{D x,y;}a[N],o;D r;int n; il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;return f*x;} il D dis(node a,node b){return sqrt((a.y-b.y)*(a.y-b.y)+(a.x-b.x)*(a.x-b.x));} il void makecir(node a,node b,node c){ D x1,y1,c1,x2,y2,c2; x1=2*(b.x-a.x);y1=2*(b.y-a.y); c1=b.x*b.x+b.y*b.y-a.x*a.x-a.y*a.y; x2=2*(c.x-a.x);y2=2*(c.y-a.y); c2=c.x*c.x+c.y*c.y-a.x*a.x-a.y*a.y; o.x=(y1*c2-y2*c1)/(y1*x2-y2*x1); o.y=(x2*c1-x1*c2)/(y1*x2-y2*x1); r=dis(o,a); } int main() { n=read();for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y); random_shuffle(a+1,a+n+1);o=a[1];r=0; for(int i=2;i<=n;i++)if(dis(o,a[i])>r){ o=a[i];r=0; for(int j=1;j<=i-1;j++)if(dis(o,a[j])>r){ o.x=(a[i].x+a[j].x)/2.0; o.y=(a[i].y+a[j].y)/2.0; r=dis(o,a[j]); for(int k=1;k<=j-1;k++)if(dis(o,a[k])>r)makecir(a[i],a[j],a[k]); } } printf("%.10lf %.10lf %.10lf ",r,o.x,o.y); return 0; }
2.网络流
(小M的作物)
#include<bits/stdc++.h> #define _(d) while(d(isdigit(ch=getchar()))) #define il inline using namespace std; const int N=3005,M=5e6+5,inf=2e9;int a[N],b[N],n,m,s,t,head[N],cnt=1,k[N],ans,res,d[N],ne[M],to[M],v[M];queue<int> q; il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;return f*x;} il void insert(int x,int y,int z){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;v[cnt]=z;} il void add(int u,int v,int w){insert(u,v,w);insert(v,u,0);} il bool bfs(){ memset(d,-1,sizeof(d));q.push(s);d[s]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=head[x];i;i=ne[i]){ if(!v[i]||d[to[i]]!=-1)continue; q.push(to[i]);d[to[i]]=d[x]+1; } } return d[t]!=-1; } int dfs(int x,int f){ if(x==t)return f;int w,used=0; for(int i=head[x];i;i=ne[i]){ if(d[x]+1!=d[to[i]]||(!v[i]))continue; w=f-used;w=dfs(to[i],min(w,v[i])); v[i]-=w;v[i^1]+=w;used+=w;if(used==f)return used; } if(!used)d[x]=-1;return used; } il void dinic(){while(bfs()){res+=dfs(s,inf);}} int main() { n=read();for(int i=1;i<=n;i++)a[i]=read(),ans+=a[i]; for(int i=1;i<=n;i++)b[i]=read(),ans+=b[i];m=read();t=n+2*m+1; for(int i=1;i<=n;i++)add(s,i,a[i]),add(i,t,b[i]); for(int i=1;i<=m;i++){ int kk=read();int c1=read(),c2=read();ans+=c1+c2;add(s,n+i,c1);add(n+m+i,t,c2); for(int j=1;j<=kk;j++){int k=read();add(n+i,k,inf);add(k,n+m+i,inf);} } dinic();printf("%d ",ans-res); return 0; }
3.STL牛逼
nth_element(a+1,a+1+m,a+n+1,greater<int>());
取出前m大的数字(前m大内是乱序)期望效率O(n)牛逼!!
4.爬树缩点
il void work(int x,int y,int z){ x=getf(x);y=getf(y); while(x^y){ if(d[x]<d[y])swap(x,y); res[x]=z;x=f[x]=getf(fa[x]); } }//f[]是并查集的爸爸,fa[]是原树上爸爸