【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
原文地址:https://www.cnblogs.com/wmrv587/p/3604259.html