zoukankan      html  css  js  c++  java
  • 【POJ各种模板汇总】(写在逆风省选前)(不断更新中)

    1、POJ1258

    水水的prim……不过poj上硬是没过,wikioi上的原题却过了

     1 #include<cstring>
     2 #include<algorithm>
     3 #include<cstdio>
     4 using namespace std;
     5 const int maxn=100,inf=1e8;
     6 int d[maxn+50],g[maxn+50][maxn+50],ans=0,n;
     7 bool v[maxn+50];
     8 int main()
     9 {
    10     scanf("%d",&n);
    11     for(int i=1;i<=n;++i)
    12         for(int j=1;j<=n;++j)
    13         {
    14             scanf("%d",&g[i][j]);
    15             if(g[i][j]==0) g[i][j]=inf;
    16         }
    17     memset(v,0,sizeof(v));
    18     for(int i=1;i<=n;++i) d[i]=g[1][i];
    19     d[1]=0;
    20     v[1]=1;
    21     for(int j=2;j<=n;++j)
    22     {
    23         int m=inf,k=j;
    24         for(int i=1;i<=n;++i)
    25             if(v[i]==0&&d[i]<m) m=d[i],k=i;
    26         ans+=m;
    27         v[k]=1;
    28         for(int i=1;i<=n;++i)
    29             if(v[i]==0&&g[k][i]<d[i]) d[i]=g[k][i];
    30     }
    31     printf("%d",ans);
    32     return 0;
    33 }
    View Code

    2、POJ1273

    sap,不过就是在标号的时候有点小失误浪费了些时间,就是应该是d[1]=n+1时才推出,不然最后一次没有增广

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 using namespace std;
     6 const int maxn=200,maxm=200,inf=1e8;
     7 struct wjmzbmr
     8 {
     9     int to,flow;
    10 }e[maxm*2+50];
    11 vector<int> g[maxn+50];
    12 int n,m,ans=0,d[maxn+50],dv[maxn+50];
    13 int dfs(int k,int flow)
    14 {
    15     if (k==n) return flow;
    16     int s=0;
    17     for(int i=0;i<g[k].size();++i)
    18     {
    19         wjmzbmr t=e[g[k][i]];
    20         if(t.flow<=0||d[k]!=d[t.to]+1) continue;
    21         int x=dfs(t.to,min(flow-s,t.flow)); 
    22         e[g[k][i]].flow-=x;
    23         e[g[k][i]^1].flow+=x;
    24         s+=x;
    25         if(s==flow) return s;
    26     }
    27     if(d[1]==n+1) return s;
    28     --dv[d[k]];
    29     if(dv[d[k]]==0) d[1]=n+1;
    30     d[k]++;
    31     dv[d[k]]++;
    32     return s;
    33 }
    34 int main()
    35 {
    36     while (scanf("%d %d",&m,&n)!=EOF)
    37     {
    38         memset(dv,0,sizeof(dv));
    39         for(int i=0;i<=n;++i) d[i]=1;
    40         ans=0;
    41         for(int i=0;i<=n;++i) g[i].clear();
    42         int l=0;
    43         for(int i=1;i<=m;++i)
    44         {
    45             int a,b,c;
    46             scanf("%d %d %d",&a,&b,&c);
    47             e[l].to=b,e[l].flow=c,g[a].push_back(l);
    48             ++l;
    49             e[l].to=a,e[l].flow=0,g[b].push_back(l);
    50             ++l;
    51         }
    52         dv[1]=n;
    53         while(d[1]<=n) ans+=dfs(1,inf);
    54         printf("%d
    ",ans);
    55     }
    56     return 0;
    57 } 
    View Code

     3、POJ1274

    匈牙利算法,此题注意多组数据

     1 #include<cstring>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<vector>
     5 using namespace std;
     6 const int maxn=400;
     7 int d[maxn+50]={0},n,m;
     8 bool f[maxn+50]={0};
     9 vector<int> g[maxn+50];
    10 bool dfs(int k)
    11 {
    12     for(int i=0;i<g[k].size();++i)
    13         if(!f[g[k][i]])
    14         {
    15             f[g[k][i]]=1;
    16             if(d[g[k][i]]==0||dfs(d[g[k][i]]))
    17             {
    18                 d[g[k][i]]=k;
    19                 return true;
    20             }
    21         }
    22     return false;
    23 }
    24 int main()
    25 {
    26     while(scanf("%d %d",&n,&m)!=EOF)
    27     {
    28     for(int i=0;i<=n+m;++i) g[i].clear();
    29     for(int i=1;i<=n;++i)
    30     {
    31         int x;
    32         scanf("%d",&x);
    33         for(int j=1;j<=x;++j)
    34         {
    35             int y;
    36             scanf("%d",&y);
    37             g[i].push_back(y+n);
    38             g[y+n].push_back(i);
    39         }
    40     }
    41     memset(d,0,sizeof(d));
    42     for(int i=1;i<=n;++i)
    43     {
    44         memset(f,0,sizeof(f));
    45         dfs(i);
    46     }
    47     int ans=0;
    48     for(int i=n+1;i<=n+m;++i)
    49         if(d[i]) ++ans;
    50     printf("%d
    ",ans);
    51     }
    52 }
    View Code

     4、POJ2182

    平衡树,用treap写的

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<ctime>
     5 const int maxn=8000;
     6 int q[maxn+50],ans[maxn+50],n,p[maxn+50]={0};
     7 struct wjmzbmr
     8 {
     9     wjmzbmr* ch[2];
    10     int size,value,key;
    11     int cmp(int x)
    12     {
    13         if(x==value) return -1;
    14         return value<x;
    15     }
    16     void maintain()
    17     {
    18         size=1;
    19         if(ch[0]!=NULL) size+=ch[0]->size;
    20         if(ch[1]!=NULL) size+=ch[1]->size;
    21     }
    22 };
    23 wjmzbmr* root=NULL;
    24 void rorate(wjmzbmr* &o,int d)
    25 {
    26     wjmzbmr *k=o->ch[d^1];
    27     o->ch[d^1]=k->ch[d];
    28     k->ch[d]=o;
    29     o->maintain();
    30     k->maintain();
    31     o=k;
    32 }
    33 void insert(wjmzbmr* &o,int x)
    34 {
    35     if(o==NULL)
    36     {
    37         o=new wjmzbmr();
    38         o->ch[0]=o->ch[1]=NULL;
    39         o->size=1;
    40         o->value=x;
    41         o->key=rand()%1000000000;
    42     }
    43     else
    44     {
    45         int d=o->cmp(x);
    46         insert(o->ch[d],x);
    47         if(o->ch[d]->key>o->key) rorate(o,d^1);
    48     }
    49     o->maintain();
    50 }
    51 void remove(wjmzbmr* &o,int x)
    52 {
    53     int d=o->cmp(x);
    54     if(d==-1)
    55         if(o->ch[0]==NULL) o=o->ch[1];
    56         else
    57             if(o->ch[1]==NULL) o=o->ch[0];
    58             else
    59             {
    60                 int d1=(o->ch[0]->key>o->ch[1]->key);
    61                 rorate(o,d1);
    62                 remove(o->ch[d1],x);
    63             }
    64     else remove(o->ch[d],x);
    65     if(o!=NULL) o->maintain();
    66 }
    67 int kth(wjmzbmr* o,int k)
    68 {
    69     int l=0;
    70     if(o->ch[0]!=NULL) l=o->ch[0]->size;
    71     if(l+1==k) return o->value;
    72     if(l+1<k) return kth(o->ch[1],k-l-1);
    73     if(l+1>k) return kth(o->ch[0],k);
    74 }
    75 int main()
    76 {
    77     freopen("ce.in","r",stdin);
    78     freopen("ce.out","w",stdout);
    79     scanf("%d",&n);
    80     for(int i=2;i<=n;++i) scanf("%d",&q[i]);
    81     for(int i=1;i<=n;++i) insert(root,i);
    82     for(int i=n;i>=2;--i) ans[i]=kth(root,q[i]+1),remove(root,ans[i]),p[ans[i]]=1;
    83     for(int i=1;i<=n;++i) if(p[i]==0) ans[1]=i;
    84     for(int i=1;i<=n;++i) printf("%d
    ",ans[i]);
    85     return 0;
    86 }
    View Code

     5、POJ2186

    有向图强联通,我用2次dfs写的,觉得挺好写的且可以直接撸出拓扑序列,尽管慢一些

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 using namespace std;
     6 const int maxn=1e5,inf=1e9;
     7 vector < int > g[maxn+50],g1[maxn+50],g2[maxn+50];
     8 bool v[maxn+50];
     9 int n,m,color[maxn+50],t[maxn+50],len,c,d[maxn+50];
    10 void dfs(int k)
    11 {
    12     v[k]=1;
    13     for(int i=0;i<g[k].size();++i)
    14         if(!v[g[k][i]]) dfs(g[k][i]);
    15     ++len;
    16     t[len]=k;
    17 }
    18 void dfs1(int k)
    19 {
    20     v[k]=1;
    21     color[k]=c;
    22     for(int i=0;i<g1[k].size();++i)
    23         if(!v[g1[k][i]]) dfs1(g1[k][i]);
    24 }
    25 bool check2(int a,int b)
    26 {
    27     if(a==b) return 0;
    28     for(int i=0;i<g2[a].size();++i)
    29         if(g2[a][i]==b) return 0;
    30     return 1;
    31 }
    32 int main()
    33 {
    34 
    35     while(scanf("%d %d",&n,&m)!=EOF)
    36     {
    37         c=0;
    38         len=0;
    39         memset(d,0,sizeof(d));
    40     for(int i=0;i<=n;++i) g[i].clear(),g1[i].clear(),g2[i].clear();
    41     for(int i=1;i<=m;++i)
    42     {
    43         int x,y;
    44         scanf("%d %d",&x,&y);
    45         g[x].push_back(y);
    46         g1[y].push_back(x);
    47     }
    48     memset(v,0,sizeof(v));
    49     memset(t,0,sizeof(t));
    50     for(int i=1;i<=n;++i) if(!v[i]) dfs(i);
    51     memset(v,0,sizeof(v));
    52     for(int i=len;i>=1;--i) if(!v[t[i]]) ++c,dfs1(t[i]);
    53     for(int i=1;i<=n;++i)
    54         for(int j=0;j<g[i].size();++j)
    55             if(check2(color[i],color[g[i][j]]))
    56                 g2[color[i]].push_back(color[g[i][j]]),++d[color[i]];
    57     int s=0,x=0;
    58     for(int i=1;i<=c;++i) if(d[i]==0) ++s,x=i;
    59     if(s>1) printf("0
    ");
    60     else
    61     {
    62         int ans=0;
    63         for(int i=1;i<=n;++i)
    64             if(color[i]==x) ++ans;
    65         printf("%d
    ",ans);
    66     }
    67     }
    68     return 0;
    69 }
    View Code

     6、POJ2187

    凸包,求最远对,Andrew算法:水平竖直排序+正反两边维护 O(nlogn)

     1 #include<cstring>
     2 #include<algorithm>
     3 #include<cstdio>
     4 using namespace std;
     5 const int maxn=50000;
     6 struct wjmzbmr
     7 {
     8     int x,y;
     9     bool operator < (const wjmzbmr& a) const
    10     {
    11         return (x<a.x)||(x==a.x&&y<a.y);
    12     }
    13 }a[maxn+50];
    14 int n,s[maxn+50],q[maxn+50],m=0,len=0;
    15 int cross(int x1,int y1,int x2,int y2)
    16 {
    17     return (x1*y2-y1*x2);
    18 }
    19 int main()
    20 {
    21     scanf("%d",&n);
    22     for(int i=1;i<=n;++i) scanf("%d %d",&a[i].x,&a[i].y);
    23     sort(a+1,a+n+1);
    24     m=2;
    25     s[1]=1,s[2]=2;
    26     for(int i=3;i<=n;++i)
    27     {
    28         while(m>=2&&cross(a[s[m]].x-a[s[m-1]].x,a[s[m]].y-a[s[m-1]].y,a[i].x-a[s[m]].x,a[i].y-a[s[m]].y)<=0) --m;
    29         s[++m]=i;
    30     }
    31     s[++m]=n-1;
    32     int k=m;
    33     for(int i=n-2;i>=1;--i)
    34     {
    35         while(m>=k&&cross(a[s[m]].x-a[s[m-1]].x,a[s[m]].y-a[s[m-1]].y,a[i].x-a[s[m]].x,a[i].y-a[s[m]].y)<=0) --m;
    36         s[++m]=i;
    37     }
    38     int ans=0;
    39     for(int i=1;i<=m-1;++i)
    40         for(int j=i+1;j<=m;++j)
    41             if((a[s[i]].x-a[s[j]].x)*(a[s[i]].x-a[s[j]].x)+(a[s[i]].y-a[s[j]].y)*(a[s[i]].y-a[s[j]].y)>ans) ans=(a[s[i]].x-a[s[j]].x)*(a[s[i]].x-a[s[j]].x)+(a[s[i]].y-a[s[j]].y)*(a[s[i]].y-a[s[j]].y);
    42     printf("%d",ans);
    43     return 0;
    44 }
    View Code

     7、POJ2019

    二维RMQ,但是有点细节要注意:就是以后打1<<(..)的时候一定要将整个都打上括号,因为<<优先级是最高的……这点小细节卡了不少时间

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 using namespace std;
     6 const int maxn=250;
     7 int mx[maxn+5][maxn+5][10],mi[maxn+5][maxn+5][10],n,b,m;
     8 int qmax(int lx,int ly,int rx,int ry)
     9 {
    10     int r=int(log(double(ry-ly+1))/log(double(2))),ans=-1;
    11     for(int i=lx;i<=rx;++i)
    12         ans=max(ans,max(mx[i][ly][r],mx[i][ry-(1<<r)+1][r]));
    13     return ans;
    14 }
    15 int qmin(int lx,int ly,int rx,int ry)
    16 {
    17     int r=int(log(double(ry-ly+1))/log(double(2))),ans=1e8;
    18     for(int i=lx;i<=rx;++i)
    19         ans=min(ans,min(mi[i][ly][r],mi[i][ry-(1<<r)+1][r]));
    20     return ans;
    21 }
    22 int main()
    23 {
    24     freopen("ce.in","r",stdin);
    25     freopen("ce.out","w",stdout);
    26     while(scanf("%d %d %d",&n,&b,&m)!=EOF)
    27     {
    28     for(int i=1;i<=n;++i)
    29         for(int j=1;j<=n;++j)
    30             {
    31                 scanf("%d",&mx[i][j][0]);
    32                 mi[i][j][0]=mx[i][j][0];
    33             }
    34     int r=int(log(double(n))/log(double(2)));
    35     for(int k=1;k<=n;++k)
    36         for(int j=1;j<=r;++j)
    37             for(int i=1;i+(1<<(j-1))-1<=n;++i)
    38             {
    39                 mx[k][i][j]=max(mx[k][i][j-1],mx[k][i+(1<<(j-1))][j-1]);
    40                 mi[k][i][j]=min(mi[k][i][j-1],mi[k][i+(1<<(j-1))][j-1]);
    41             }
    42     for(int i=1;i<=m;++i)
    43     {
    44         int lx,ly,rx,ry;
    45         scanf("%d %d",&lx,&ly);
    46         rx=min(n,lx+b-1);
    47         ry=min(ly+b-1,n);
    48         printf("%d
    ",qmax(lx,ly,rx,ry)-qmin(lx,ly,rx,ry));
    49     }
    50     }
    51     return 0;
    52 }
    View Code

     8、POJ1988

    并查集,练练手

     1 #include<cstring>
     2 #include<algorithm>
     3 #include<cstdio>
     4 using namespace std; 
     5 const int maxn=300000;
     6 int f[maxn+50],n,before[maxn+50],len[maxn+50];
     7 int find(int x)
     8 {
     9     if(f[x]==x) return x;
    10     int k=find(f[x]);
    11     len[x]=len[k];
    12     before[x]+=before[f[x]];
    13     return f[x]=k;
    14 }
    15 int main()
    16 {
    17     scanf("%d
    ",&n);
    18     for(int i=1;i<=n;++i) f[i]=i,len[i]=1,before[i]=0;
    19     for(int i=1;i<=n;++i)
    20     {
    21         char c;
    22         scanf("%c ",&c);
    23         if(c=='M')
    24         {
    25             int x,y;
    26             scanf("%d %d
    ",&x,&y);
    27             x=find(x),y=find(y);
    28             if(x!=y)
    29             {
    30                 f[x]=y;
    31                 before[x]=len[y];
    32                 len[y]+=len[x];
    33             }
    34         }
    35         else
    36         {
    37             int q;
    38             scanf("%d
    ",&q);
    39             int k=find(q);
    40             printf("%d
    ",before[q]);
    41         }
    42     }
    43     return 0;
    44 }
    View Code

     9、POJ3666

    静态主席树求区间k小(此题是求中位数,左偏树也能搞)

     1 #include<cstring>
     2 #include<algorithm>
     3 #include<cstdio>
     4 using namespace std;
     5 const int maxn=2000;
     6 struct wjmzbmr
     7 {
     8        int l,r,ls,rs,sum;
     9 }f[maxn*20];
    10 struct fotile96
    11 {
    12        int l,r,mid;
    13 }stack[maxn+50];
    14 int a[maxn+50],sorta[maxn+50],root[maxn+50],n,len=0;
    15 int build(int l,int r)
    16 {
    17      int k=++len;
    18      f[k].l=l,f[k].r=r,f[k].ls=f[k].rs=f[k].sum=0;
    19      if(l==r) return len;
    20      int mid=(l+r)>>1;
    21      f[k].ls=build(l,mid);
    22      f[k].rs=build(mid+1,r);
    23      return k;
    24 }
    25 int change(int root,int x)
    26 {
    27     int k=++len;
    28     f[k]=f[root],f[k].sum+=1;
    29     if(f[k].l==f[k].r) return k;
    30     int mid=(f[k].l+f[k].r)>>1;
    31     if(x<=mid) f[k].ls=change(f[k].ls,x);else f[k].rs=change(f[k].rs,x);
    32     return k;
    33 }
    34 int ask(int a,int b,int k)
    35 {
    36     if(f[b].l==f[b].r) return f[b].r;
    37     int mid=f[f[b].ls].sum-f[f[a].ls].sum;
    38     if(k<=mid) return ask(f[a].ls,f[b].ls,k);else return ask(f[a].rs,f[b].rs,k-mid);
    39 }
    40 int main()
    41 {
    42     scanf("%d",&n);
    43     for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    44     for(int i=1;i<=n;++i) sorta[i]=a[i];
    45     sort(sorta+1,sorta+n+1);
    46     int q=1;
    47     for(int i=2;i<=n;++i) if(sorta[i]!=sorta[q]) sorta[++q]=sorta[i];
    48     root[0]=build(1,q);
    49     for(int i=1;i<=n;++i)
    50     {
    51             int x=lower_bound(sorta+1,sorta+q+1,a[i])-sorta;
    52             root[i]=change(root[i-1],x);
    53     }
    54     len=1;
    55     stack[len].l=stack[len].r=1,stack[len].mid=a[1];
    56     for(int i=2;i<=n;++i)
    57     {
    58             ++len;
    59             stack[len].l=stack[len].r=i,stack[len].mid=a[i];
    60             while (len>1&&stack[len].mid<stack[len-1].mid)
    61             {
    62                   stack[len-1].r=stack[len].r;
    63                   --len;
    64                   stack[len].mid=sorta[ask(root[stack[len].l-1],root[stack[len].r],(stack[len].r-stack[len].l+1)/2+1)];
    65             }
    66     }
    67     int ans=0;
    68     for (int i=1;i<=len;++i) 
    69         for (int j=stack[i].l;j<=stack[i].r;++j)
    70             ans+=abs(a[j]-stack[i].mid);
    71     printf("%d",ans);
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    Elixir 简介
    docker 基础
    函数式和面向对象
    react-native 简介及环境
    Ecto 总结
    使用 dep 配置 golang 开发环境
    docker 私有仓库简易搭建
    Elixir 单元测试
    基于资源的权限系统-API设计
    差商代微商的方法求解一阶常微分方程
  • 原文地址:https://www.cnblogs.com/wmrv587/p/3604259.html
Copyright © 2011-2022 走看看