ACM模板(持续更新)

十年热恋 提交于 2020-03-30 15:55:48

数据的离散化存储+去重

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+7;
 4 int a[maxn];
 5 vector<int> g;
 6 int getid(int x)
 7 {
 8     return lower_bound(g.begin(),g.end(),x)-g.begin()+1;
 9 }
10 int main()
11 {
12     int n;
13     cin>>n;
14     for(int i=0;i<n;++i){
15         cin>>a[i];
16         g.push_back(a[i]);
17     }
18     sort(g.begin(),g.end());
19     g.erase(unique(g.begin(),g.end()),g.end());
20     return 0;
21 }
View Code

KMP

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstring>
 4 using namespace std;
 5 void get_next(char *str,int *next,int len)
 6 {
 7     int i=0,j=-1;
 8     next[0]=-1;
 9     while(i<len)
10     {
11         if(j==-1||str[i]==str[j]){
12             ++i;
13             ++j;
14             next[i]=j;
15         }else
16             j=next[j];
17     }
18 }
19 int Index_KMP(char *s1,char *s2,int len1,int len2)
20 {
21     int i=0,j=-1;
22     int next[200];
23     get_next(s2,next,len2);
24     while(i<len1&&j<len2)
25     {
26         if(j==-1||s1[i]==s2[j]){
27             ++i;
28             ++j;
29         }else
30             j=next[j];
31     }
32     if(j>=len2)
33         return i-j+1;
34     else
35         return 0;
36 }
37 int main()
38 {
39     char s1[200],s2[200];
40     cin>>s1>>s2;
41     int len1=strlen(s1);
42     int len2=strlen(s2);
43     int pos=Index_KMP(s1,s2,len1,len2);
44     cout<<pos<<endl;
45     return 0;
46 }
View Code

AC自动机(指针版)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+7;
 4 typedef struct node{
 5     char c;
 6     struct node *next[26];
 7     struct node *fail,*father;
 8     bool flag;
 9     void init()
10     {
11         for(int i=0;i<26;++i)
12             next[i]=NULL;
13         flag=false;
14     }
15 } node;
16 node *root=new node;
17 void build(char str[][10010],int num)
18 {
19     int len,x;
20     node *p,*r;
21     root->fail=root;
22     for(int i=0;i<num;++i){
23         p=root;
24         len=strlen(str[i]);
25         for(int j=0;j<len;++j){
26             x=str[i][j]-'a';
27             if(!p->next[x]){
28                 p->next[x]=new node;
29                 p->next[x]->init();
30                 p->next[x]->fail=root;
31                 p->next[x]->father=p;
32                 p->next[x]->c=str[i][j];
33             }
34             p=p->next[x];
35             if(j==len-1)
36                 p->flag=true;
37         }
38     }
39     queue<node*> q;
40     q.push(root);
41     while(!q.empty())
42     {
43         p=q.front();
44         q.pop();
45         for(int i=0;i<26;++i){
46             if(p->next[i])
47                 q.push(p->next[i]);
48         }
49         if(p==root)
50             continue;
51         x=p->c-'a';
52         r=p->father->fail;
53         if(r->next[x]&&r->next[x]!=p)
54             p->fail=r->next[x];
55     }
56 }
57 int AC_automachine(char str[])
58 {
59     int ans=0,len=strlen(str),x;
60     node *p=root;
61     for(int i=0;i<len;++i){
62         x=str[i]-'a';
63         if(p->next[x]){
64             p=p->next[x];
65             if(p->flag)
66                 ans++;
67         }else{
68             p=p->fail;
69             if(p->flag)
70                 ans++;
71             if(p!=root)
72                 --i;
73         }
74         //cout<<i<<endl;
75     }
76     return ans;
77 }
78 char str[51][10010];
79 char s[maxn];
80 int main()
81 {
82     cin.tie(0);
83     ios::sync_with_stdio(false);
84     //freopen("in.txt","r",stdin);
85     int n,t;
86     cin>>t;
87     while(t--)
88     {
89         root->init();
90         cin>>n;
91         for(int i=0;i<n;++i)
92             cin>>str[i];
93         build(str,n);
94         cin>>s;
95         cout<<AC_automachine(s)<<endl;
96     }
97     return 0;
98 }
View Code

AC自动机(数组版)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e6+7;
  4 const int N=5e5+7;
  5 struct Aho{
  6     struct Node{
  7         int next[26];
  8         int fail,cnt;
  9     }node[N];
 10     int size;
 11     void init()
 12     {
 13         for(int i=0;i<N;++i){
 14             memset(node[i].next,0,sizeof(node[i].next));
 15             node[i].fail=node[i].cnt=0;
 16         }
 17         size=1;
 18     }
 19     void insert(char *str)
 20     {
 21         int len=strlen(str);
 22         int now=0;
 23         for(int i=0;i<len;++i){
 24             int x=str[i]-'a';
 25             if(!node[now].next[x])
 26                 node[now].next[x]=size++;
 27             now=node[now].next[x];
 28         }
 29         node[now].cnt++;
 30     }
 31     void build()//构建fail指针
 32     {
 33         queue<int> q;
 34         node[0].fail=-1;
 35         q.push(0);
 36         while(!q.empty())
 37         {
 38             int u=q.front();
 39             q.pop();
 40             for(int i=0;i<26;++i){
 41                 if(node[u].next[i]){
 42                     if(u==0)//如果是根节点的子节点,那么fail指针一定指向根
 43                         node[node[u].next[i]].fail=0;
 44                     else{
 45                         int v=node[u].fail;
 46                         while(v!=-1)
 47                         {
 48                             if(node[v].next[i]){//如果父节点的fail指针指向的节点指向点有对应的子节点,
 49                                     //就将fail指针指向此节点
 50                                 node[node[u].next[i]].fail=node[v].next[i];
 51                                 break;
 52                             }
 53                             v=node[v].fail;
 54                         }
 55                         if(v==-1)
 56                             node[node[u].next[i]].fail=0;
 57                     }
 58                     q.push(node[u].next[i]);
 59                 }
 60             }
 61         }
 62     }
 63     int get(int u)
 64     {
 65         int ans=0;
 66         while(u)
 67         {
 68             ans+=node[u].cnt;
 69             node[u].cnt=0;
 70             u=node[u].fail;
 71         }
 72         return ans;
 73     }
 74     int math(char *s)
 75     {
 76         int len=strlen(s);
 77         int ans=0,now=0;
 78         for(int i=0;i<len;++i){
 79             int x=s[i]-'a';
 80             if(node[now].next[x])
 81                 now=node[now].next[x];
 82             else{
 83                 int p=node[now].fail;
 84                 while(p!=-1&&node[p].next[x]==0)
 85                     p=node[p].fail;
 86                 if(p==-1)
 87                     now=0;
 88                 else
 89                     now=node[p].next[x];
 90             }
 91             if(node[now].cnt)
 92                 ans+=get(now);
 93         }
 94         return ans;
 95     }
 96 }aho;
 97 char s[maxn];
 98 int main()
 99 {
100     ios::sync_with_stdio(false);
101     int t,n;
102     cin>>t;
103     while(t--)
104     {
105         aho.init();
106         cin>>n;
107         for(int i=0;i<n;++i){
108             cin>>s;
109             aho.insert(s);
110         }
111         aho.build();
112         cin>>s;
113         int ans=aho.math(s);
114         cout<<ans<<endl;
115     }
116     return 0;
117 }
View Code

并查集

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const  int maxn=1010;
 4 
 5 void Init(int *father,int *rank)
 6 {
 7     for(int i=0;i<maxn;++i){
 8         father[i]=i;
 9         rank[i]=0;
10     }
11 }
12 //int FindSet1(int x,int *father)
13 //{
14 //    int r=x,j;
15 //    while(x!=father[x])
16 //        x=father[x];
17 //    while(r!=x)
18 //    {
19 //        j=father[r];
20 //        father[r]=x;
21 //        r=j;
22 //    }
23 //    return x;
24 //}
25 int FindSet2(int x,int *father)
26 {
27 
28     if(x!=father[x])
29         father[x]=FindSet2(father[x],father);
30     return father[x];
31 }
32 bool Union(int x,int y,int *father,int *rank)
33 {
34     x=FindSet1(x,father);
35     y=FindSet1(y,father);
36     if(x==y)
37         return false;
38     if(rank[x]>rank[y])
39         father[y]=x;
40     else{
41         if(rank[x]==rank[y])
42             rank[y]++;
43         father[x]=y;
44     }
45     return true;
46 }
47 int main()
48 {
49     int n,x,y;
50     int father[maxn],rank[maxn];
51     Init(father,rank);
52     cin>>n;
53     for(int i=0;i<n;++i){
54         cin>>x>>y;
55         bool flag=Union(x,y,father,rank);
56         if(flag)
57             cout<<"Successful"<<endl;
58         else
59             cout<<"Set has exist"<<endl;
60     }
61     return 0;
62 }
View Code

二分查找

 1 #include<stdio.h>
 2 
 3 int search(int tar,int a[],int len)
 4 {
 5     int ret=-1;
 6     int left=0,right=len-1,mid;
 7     while(right>left)
 8     {
 9         mid=(right+left)/2;
10         if(a[mid]==tar){
11             ret=mid;
12             break;
13         }else if(a[mid]>tar){
14             right=mid-1;
15         }else{
16             left=mid+1;
17         }
18     }
19     return ret;
20 }
21 int main()
22 {
23     int n,i;
24     int a[]={1,2,7,8,18,45,66,67,88,169,198};
25     scanf("%d",&n);
26     i=search(n,a,sizeof(a)/sizeof(a[0]));
27     printf("%d\n",i);
28     return 0;
29 }
View Code

矩阵快速幂

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int NUM=5;
 5 const int mod=998244353;
 6 struct Mat{
 7     int n,m;
 8     ll a[NUM][NUM];
 9 };
10 Mat mul(Mat a,Mat b)
11 {
12     Mat ans;
13     ans.n=a.n;
14     ans.m=b.m;
15     for(int i=0;i<ans.n;++i)
16     for(int j=0;j<ans.m;++j){
17         ans.a[i][j]=0;
18         for(int k=0;k<a.m;++k){
19             ans.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod;
20             ans.a[i][j]%=mod;
21         }
22     }
23     return ans;
24 }
25 Mat power(Mat a,int num)
26 {
27     Mat ans;
28     ans.n=2;
29     ans.m=1;
30     ans.a[0][0]=ans.a[1][0]=1;
31     while(num)
32     {
33         if(num&1)
34             ans=mul(ans,a);
35         num>>=1;
36         a=mul(a,a);
37     }
38     return ans;
39 }
40 int main()
41 {
42     //freopen("data.txt","r",stdin);
43     //freopen("out1.txt","w",stdout);
44     ios::sync_with_stdio(false);
45     int n;
46     Mat a;
47     a.n=a.m=2;
48     a.a[0][0]=0;
49     a.a[0][1]=a.a[1][0]=a.a[1][1]=1;
50     while(cin>>n)
51     {
52         Mat ans=power(a,n*2+3);
53         cout<<((ans.a[0][1]-1)%mod+mod)%mod<<endl;
54     }
55     return 0;
56 }
View Code

欧几里得

1 int gcd(int a,int b)
2 {
3     return b==0?a:gcd(b,a%b);
4 }
View Code

拓展欧几里得

 1 int exGcd(a a,a b,a &x,a &y)
 2 {
 3     if(b==0){
 4         x=1;y=0;
 5         return a;
 6     }
 7     int r=exGcd(b,a%b,x,y);
 8     int t=x;
 9     x=y;
10     y=t-a/b*y;
11 }
View Code

线性筛

 1 const int maxn=1e6+10;
 2 bool isprime[maxn];
 3 int prime[maxn];
 4 int primenum;
 5 void getprime(int limit)
 6 {
 7     primenum=0;
 8     memset(isprime,true,sizeof(isprime));
 9     isprime[0]=isprime[1]=false;
10     for(int i=2;i<=limit;++i){
11         if(isprime[i])
12             prime[++primenum]=i;
13         for(int j=1;j<=primenum&&i*prime[j]<=limit;++j){
14             isprime[i*prime[j]]=false;
15             if(i%prime[j]==0)
16                 break;
17         }
18     }
19 }
View Code

较小组合数求模

 1 int num[maxn][maxn];
 2 int C(int n,int k)
 3 {
 4     if(k>n)
 5         return 0;
 6     return num[n][k];
 7 }
 8 void Cal(int n)
 9 {
10     for(int i=0;i<=n;++i){
11         num[i][0]=1;
12         for(int j=1;j<i;++j)
13             num[i][j]=(C(i-1,j-1)%mod+C(i-1,j)%mod)%mod;
14         num[i][i]=1;
15     }
16 }
View Code

矩阵乘法

1 void mult(int **a,int **b,int **c)
2 {
3     memset(c,0,sizeof(c));
4     for(int i=0;i<N;++i)
5         for(int j=0;j<N;++j)
6             for(int l=0;l<N;++l)
7                 c[i][j]+=a[i][l]*b[l][j];
8 }
View Code

求逆元

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 void ex_gcd(LL a,LL b,LL &x,LL &y,LL &d)
 5 {
 6     if(!b)
 7         d=a,x=1,y=0;
 8     else {
 9         ex_gcd(b,a%b,y,x,d);
10         y-=x*(a/b);
11     }
12 }
13 LL inv1(LL a,LL p)
14 {
15      LL d,x,y;
16      ex_gcd(a,p,x,y,d);
17      return d==1?(x%p+p)%p:-1;
18 }
19 LL inv2(LL a,LL p)
20 {
21     return a==1?1:(p-p/a)*inv(p%t,p)%p;
22 }
23 int main()
24 {
25     LL a,p;
26     while(cin>>a>>p)
27         cout<<inv1(a,p)<<endl;
28     return 0;
29 }
View Code

欧拉函数

 1 //欧拉函数是求小于等于n的数中与n互质的数的数目
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 const int maxn=1e6+7;
 5 int phi[maxn],prime[maxn];
 6 int tot;
 7 void Euler()
 8 {
 9     phi[1]=1;
10     for(int i=2;i<N;++i){
11         if(!phi[i]){
12             phi[i]=i-1;
13             prime[tot++]=i;
14         }
15         for(int j=0;j<tot&&i*prime[j]<maxn;++j){
16             if(i%prime[j])
17                 phi[i*prime[j]]=phi[i]*(prime[j]-1);
18             else{
19                 phi[i*prime[j]]=phi[i]*prime[j];
20                 break;
21             }
22         }
23     }
24 }
25 int main()
26 {
27     Euler();
28     return 0;
29 }
View Code

中国剩余定理

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3  //n个方程:x=a[i](mod m[i]) (0<=i<n)
 4  LL china(int n, LL *a, LL *m){
 5      LL M = 1, ret = 0;
 6      for(int i = 0; i < n; i ++) M *= m[i];
 7      for(int i = 0; i < n; i ++){
 8         LL w = M / m[i];
 9         ret = (ret + w * inv(w, m[i]) * a[i]) % M;
10     }
11     return (ret + M) % M;
12  }
View Code

Lucas定理

1 LL Lucas(LL n, LL m, int p)
2 {
3          return m ? Lucas(n/p, m/p, p) * comb(n%p, m%p, p) % p : 1;
4 }
View Code

高精度求模

1 int get_mod(string a,int mod)
2 {
3     int ans=0;
4     for(int i=0;i<a.size();++i)
5         ans=(ans*10+(a[i]-'0'))%mod;
6     return ans;
7 }
View Code

莫队算法

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e6+7;
 5 struct node{
 6     int l,r,id;
 7 }query[maxn];
 8 ll Ans=0,a[i],ans[maxn];
 9 int pos[maxn],L=0,R=1;
10 bool cmp(node a,node b)
11 {
12     if(pos[a.l]==pos[b.l])
13         return a.r<b.r;
14     return pos[a.l]<pos[b.l];
15 }
16 void add(int x)
17 {
18 
19 }
20 
21 void del(int x)
22 {
23 
24 }
25 int main()
26 {
27     int n,m,sz;
28     cin>>n>>m;
29     sz=sqrt(n);
30     for(int i=1;i<=n;++i){
31         cin>>a[i];
32         a[i]+=a[i-1];
33         pos[i]=i/sz;
34     }
35     for(int i=1;i<=m;++i){
36         cin>>query[i].l>>query[i].r;
37         query[i].id=i;
38     }
39     sort(query+1,query+1+m);
40     for(int i=1;i<=m;++i){
41         while(L<query[i].l)
42         {
43             del(L-1);
44             ++L;
45         }
46         while(L>query[i].l)
47         {
48             --L;
49             add(L-1);
50         }
51         while(R<query[i].r)
52         {
53             ++R;
54             add(R);
55         }
56         while(R>query[i].r)
57         {
58             del(R);
59             --R;
60         }
61         ans[query[i].id]=Ans;
62     }
63     for(int i=1;i<=m;++i)
64         cout<<ans[i]<<endl;
65     return 0;
66 }
View Code

线段树(点修改)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=100010;
 4 int a[maxn],tree[maxn*2];
 5 void build(int l,int r,int k)
 6 {
 7     if(l>r)
 8         return ;
 9     if(l==r)
10         tree[k]=a[l];
11     int mid=(l+r)>>1;
12     build(l,mid,2*k);
13     build(mid+1,r,2*k+1);
14     tree[k]=tree[2*k]+tree[2*k+1];
15 }
16 void change(int l,int r,int cl,int cr,int k,int x)
17 {
18     if(l>cr||r<cl||l>r)
19         return ;
20     if(l==r){
21         tree[k]+=x;
22         return;
23     }
24     int mid=(l+r)>>1;
25     change(l,mid,cl,cr,2*k,x);
26     change(mid+1,r,cl,cr,2*k+1,x);
27     tree[k]=tree[k]=tree[2*k]+tree[2*k+1];
28 }
29 int query(int l,int r,int ql,int qr,int k)
30 {
31     if(l>cr||r<cl||l>r)
32         return 0;
33     if(l>ql&&r<qr)
34         return tree[k];
35     int mid=(l+r)>>1;
36     return query(l,mid,ql,qr,2*k)+query(mid+1,r,ql,qr,2*k+1);
37 }
38 int main()
39 {
40     int n;
41     cin>>n;
42     for(int i=1;i<=n;++i)
43         cin>>a[i];
44     build(1,n,1);
45 
46     return 0;
47 }
View Code

线段树(区间修改)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 int a[maxn];
 5 int sum[maxn<<2],exc[maxn<<2];
 6 void maintain(int k)
 7 {
 8     sum[k]=sum[k<<1]+sum[k<<1|1];
 9 }
10 void pushdown(int lenl,int lenr,int k)//标记下放,并更细节点信息
11 {
12     if(exc[k]){
13         exc[k<<1]=exc[k];
14         exc[k<<1|1]=exc[k];
15         sum[k<<1]=exc[k]*lenl;
16         sum[k<<1|1]=exc[k]*lenr;
17         exc[k]=0;
18     }
19 }
20 void build(int l,int r,int k)
21 {
22     if(l>r)
23         return ;
24     if(l==r){
25         sum[k]=a[l];
26         exc[k]=0;
27         return ;
28     }
29     int mid=(l+r)>>1;
30     build(l,mid,k<<1);
31     build(mid+1,r,k<<1|1);
32     maintain(k);
33 }
34 void change(int l,int r,int cl,int cr,int k,int newp)
35 {
36     if(l>r||cl>r||cr<l)
37         return ;
38     if(l>=cl&&r<=cr){
39         sum[k]=newp*(r-l+1);//在发现现在区域小于需要更新区域时
40         exc[k]=newp;//更新节点的结果,并增加延迟标记exc,用于之后的标记下放
41         return ;
42     }
43     int mid=(l+r)>>1;
44     pushdown(mid-l+1,r-mid,k);
45     change(l,mid,cl,cr,k<<1,newp);
46     change(mid+1,r,cl,cr,k<<1|1,newp);
47     maintain(k);
48 }
49 int query(int l,int r,int ql,int qr,int k)
50 {
51     if(l>r||ql>r||qr<l)
52         return 0;
53     if(l>=ql&&r<=qr)
54         return sum[k];
55     int mid=(l+r)>>1,ans=0;
56     pushdown(mid-l+1,r-mid,k);//每一层询问执行到这一步,为了下一次递归更新叶节点信息
57     if(mid>=l)
58         ans+=query(l,mid,ql,qr,k<<1);
59     if(mid<r)
60         ans+=query(mid+1,r,ql,qr,k<<1|1);
61     return ans;
62 }
63 int main()
64 {
65     ios::sync_with_stdio(false);
66     //freopen("in.txt","r",stdin);
67     int n,m,cmd,l,r,newp;
68     cin>>n;
69     for(int i=1;i<=n;++i)
70         cin>>a[i];
71     build(1,n,1);
72     cin>>m;
73     for(int i=0;i<m;++i){
74         cin>>cmd>>l>>r;
75         if(cmd){
76             cin>>newp;
77             change(1,n,l,r,1,newp);
78         }else
79             cout<<query(1,n,l,r,1)<<endl;
80     }
81     return 0;
82 }
View Code

树上倍增

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+7;
 4 vector<int> mp[maxn];
 5 int dep[maxn],fa[maxn][40],size[maxn];
 6 void dfs(int x,int last)
 7 {
 8     int v;
 9     dep[x]=dep[last]+1;
10     fa[x][0]=last;
11     size[x]=1;
12     for(int i=0;i<mp[x].size();++i){
13         v=mp[x][i];
14         if(v!=last){
15             dfs(v,x);
16             size[x]+=size[i];
17         }
18     }
19 }
20 int lca(int a,int b,int n)
21 {
22     for(int j=1;j<=20;++j)
23         for(int i=1;i<=n;++i)
24             fa[i][j]=fa[fa[i][j-1]][j-1];
25     if(dep[a]<dep[b])
26         swap(a,b);
27     int d=dep[a]-dep[b];
28     for(int i=0;i<=20;++i)
29         if((1<<i)&d)
30             a=fa[a][d];
31     for(int i=20;i>=0;--i)
32     if(fa[a][i]!=fa[b][i]){
33         a=fa[a][i];
34         b=fa[b][i];
35     }
36     if(a==b)
37         return a;
38     else
39         return fa[a][0];
40 }
41 int main()
42 {
43     int n,u,v;
44     cin>>n;
45     for(int i=0;i<n;++i){
46         cin>>u>>V;
47         mp[u].push_back(v);
48         mp[v].push_back(u);
49     }
50     dfs(1,0);
51     cin>>u>>v;
52     cout<<lca(u,v,n)<<endl;
53     return 0;
54 }
View Code

树链剖分

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=3e4+7;
  4 const int INF=1<<30;
  5 int weight[maxn],id[maxn],son[maxn],dep[maxn];
  6 int father[maxn],size[maxn],root[maxn];
  7 int idx=0;
  8 struct node{
  9     int l,r;
 10     int maxx,sum;
 11 }tree[maxn<<2];
 12 vector<int> g[maxn];
 13 void dfs(int x,int last,int d)
 14 {
 15     dep[x]=d;
 16     size[x]=1;
 17     father[x]=last;
 18     son[x]=0;
 19     int v;
 20     for(int i=0;i<g[x].size();++i){
 21         v=g[x][i];
 22         if(v==last)
 23             continue;
 24         dfs(v,x,d+1);
 25         if(i==0)
 26             son[x]=v;
 27         else if(size[son[x]]<size[v])
 28             son[x]=v;
 29         size[x]+=size[v];
 30     }
 31 }
 32 void connect(int x,int r)
 33 {
 34     int v;
 35     root[x]=r;
 36     id[x]=++idx;
 37     if(son[x]!=0){
 38         connect(son[x],r);
 39         for(int i=0;i<g[x].size();++i){
 40             v=g[x][i];
 41             if(v!=father[x]&&v!=son[x])
 42                 connect(v,v);
 43         }
 44     }
 45 }
 46 void build(int l,int r,int k)
 47 {
 48     if(l>r)
 49         return ;
 50     tree[k].l=l;
 51     tree[k].r=r;
 52     if(l==r)
 53         return ;
 54     int mid=(l+r)>>1;
 55     build(l,mid,k<<1);
 56     build(mid+1,r,k<<1|1);
 57 }
 58 void change(int tar,int w,int k)
 59 {
 60     int l=tree[k].l;
 61     int r=tree[k].r;
 62     if(l==r){
 63         tree[k].maxx=w;
 64         tree[k].sum=w;
 65         return ;
 66     }
 67     int mid=(l+r)>>1;
 68     if(tar<=mid)
 69         change(tar,w,k<<1);
 70     else
 71         change(tar,w,k<<1|1);
 72     tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
 73     tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
 74 }
 75 int query_max(int ql,int qr,int k)
 76 {
 77     int l=tree[k].l;
 78     int r=tree[k].r;
 79     if(ql>r||qr<l)
 80         return -INF;
 81     if(ql<=l&&qr>=r)
 82         return tree[k].maxx;
 83     int mid=(l+r)>>1;
 84     return max(query_max(ql,qr,k<<1),query_max(ql,qr,k<<1|1));
 85 }
 86 int query_sum(int ql,int qr,int k)
 87 {
 88     int l=tree[k].l;
 89     int r=tree[k].r;
 90     if(ql>r||qr<l)
 91         return 0;
 92     if(ql<=l&&qr>=r)
 93         return tree[k].sum;
 94     int mid=(l+r)>>1;
 95     return query_sum(ql,qr,k<<1)+query_sum(ql,qr,k<<1|1);
 96 }
 97 int Cal_Sum(int qa,int qb)
 98 {
 99     int sum=0;
100     while(root[qa]!=root[qb])
101     {
102         if(dep[root[qa]]<dep[root[qb]])
103             swap(qa,qb);
104         sum+=query_sum(id[root[qa]],id[qa],1);
105         qa=father[root[qa]];
106 
107     }
108     if(id[qa]>id[qb])
109         swap(qa,qb);
110     sum+=query_sum(id[qa],id[qb],1);
111     return sum;
112 }
113 int Cal_Max(int qa,int qb)
114 {
115     int maxx=-INF;
116     while(root[qa]!=root[qb])
117     {
118         if(dep[root[qa]]<dep[root[qb]])
119             swap(qa,qb);
120         maxx=max(maxx,query_max(id[root[qa]],id[qa],1));
121         qa=father[root[qa]];
122     }
123     if(id[qa]>id[qb])
124         swap(qa,qb);
125     maxx=max(maxx,query_max(id[qa],id[qb],1));
126     return maxx;
127 }
128 int main()
129 {
130     //freopen("in.txt","r",stdin);
131     int n,v,u,q;
132     char cmd[10];
133     scanf("%d",&n);
134     for(int i=1;i<n;++i){
135         scanf("%d%d",&u,&v);
136         g[u].push_back(v);
137         g[v].push_back(u);
138     }
139 
140     for(int i=1;i<=n;++i)
141         scanf("%d",&weight[i]);
142     dfs(1,1,1);
143     connect(1,1);
144     build(1,n,1);
145     for(int i=1;i<=n;++i)
146         change(id[i],weight[i],1);
147     scanf("%d",&q);
148     for(int i=0;i<q;++i){
149         scanf("%s%d%d",cmd,&u,&v);
150         if(cmd[0]=='C')
151             change(id[u],v,1);
152         else if(cmd[1]=='S')
153             printf("%d\n",Cal_Sum(u,v));
154         else
155             printf("%d\n",Cal_Max(u,v));
156     }
157     return 0;
158 }
View Code

SPFA

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
const int INF=0x3F;
struct node{
    int to,len;
};
vector<node> g[maxn];
int shortlen[maxn],cnt[maxn];
int n,m,s,t;
bool visit[maxn];
bool spfa()
{
    memset(shortlen,INF,sizeof(shortlen));
    memset(visit,false,sizeof(visit));
    memset(cnt,0,sizeof(cnt));
    queue<int> q;
    q.push(s);
    shortlen[s]=0;
    visit[s]=true;
    while(!q.empty())
    {
        s=q.front();
        q.pop();
        visit[s]=false;
        for(int i=0;i<g[s].size();++i){
            if(shortlen[s]+g[s][i].len<shortlen[g[s][i].to]){
                shortlen[g[s][i].to]=shortlen[s]+g[s][i].len;
                if(!visit[g[s][i].to]){
                    visit[g[s][i].to]=true;
                    q.push(g[s][i].to);
                    cnt[g[s][i].to]++;
                    if(cnt[g[s][i]].to>n)
                        return false;
                }
            }
        }
    }
    cout<<shortlen[t]<<endl;
    return true;
}
int main()
{
    ios::sync_with_stdio(false);
    //freopen("in.txt","r",stdin);
    int u,v;
    node a;
    cin>>n>>m>>s>>t;
    for(int i=0;i<m;++i){
        cin>>u>>v>>a.len;
        a.to=v;
        g[u].push_back(a);
        a.to=u;
        g[v].push_back(a);
    }
    spfa();
    return 0;
}
View Code

迪杰斯特拉

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 const int INF=65535;
 9 const int maxn=110;
10 unsigned int mp[maxn][maxn];
11 bool visit[maxn];
12 unsigned int shortlen[maxn];
13 typedef struct Node{
14     int dis,v;
15     bool operator < (const Node &cmp) const{//重载小于号,不理解的可以直接用。作用相当于定义一个优先队列的比较规则
16         return dis > cmp.dis;
17     }
18 }Node;
19 void Dijkstra(int start,int num)
20 {
21     int value;
22     memset(visit,false,sizeof(visit));
23     memset(shortlen,INF,sizeof(shortlen));
24     priority_queue<Node> q;
25     shortlen[start]=0;
26     q.push({0,start});//起点放入队列
27     while(!q.empty())
28     {
29         Node a=q.top();//取出
30         q.pop();
31         start=a.v;
32         value=shortlen[start];
33         visit[start]=true;//记为访问过
34         for(int i=1;i<=num;++i){
35             if(i==start)
36                 continue;
37             if(mp[start][i]<INF&&visit[i]==false){
38                     if(mp[start][i]+value<shortlen[i])
39                         shortlen[i]=mp[start][i]+value;//更新数组
40                     q.push({shortlen[i],i});
41                }
42         }
43     }
44 }
45 int main()
46 {
47 //    freopen("in.txt","r",stdin);
48     int numv;
49     int x,y,w,v;
50     cout<<"InPut the number of v"<<endl;
51     cin>>numv;
52     memset(mp,INF,sizeof(mp));
53     cout<<"Build Map"<<endl;
54     while(cin>>x>>y&&(x||y))
55     {
56         cin>>w;
57         mp[x][y]=w;
58         mp[y][x]=w;
59     }
60     cout<<"Input the start"<<endl;
61     cin>>v;
62 
63     Dijkstra(v,numv);
64     for(int i=1;i<=numv;++i)
65         cout<<"i="<<i<<" shortlen="<<shortlen[i]<<endl;
66     cout<<endl;
67     return 0;
68 }
View Code

克鲁斯卡尔

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=110;
 4 typedef struct{
 5     int begin,end,weight;
 6 }Edge;
 7 int FindSet(int x,int *father)
 8 {
 9 
10     if(x!=father[x])
11         father[x]=FindSet(father[x],father);
12     return father[x];
13 }
14 bool Union(int x,int y,int *father,int *rank)
15 {
16     x=FindSet(x,father);
17     y=FindSet(y,father);
18     if(x==y)
19         return false;
20     if(rank[x]>rank[y])
21         father[y]=x;
22     else{
23         if(rank[x]==rank[y])
24             rank[y]++;
25         father[x]=y;
26     }
27     return true;
28 }
29 bool cmp(Edge a,Edge b)
30 {
31     return a.weight<b.weight;
32 }
33 bool isfull(bool *flag,int n)
34 {
35     for(int i=0;i<n;++i){
36         if(!flag[i])
37             return false;
38     }
39     return true;
40 }
41 int main()
42 {
43    // freopen("in.txt","r",stdin);
44     Edge a[maxn];
45     bool flag[maxn];
46     int v,e;
47     cin>>v>>e;
48     memset(flag,false,sizeof(flag));
49     for(int i=0;i<e;++i)
50         cin>>a[i].begin>>a[i].end>>a[i].weight;
51     int father[maxn],rank[maxn];
52     for(int i=0;i<v;++i){
53         father[i]=i;
54         rank[i]=0;
55     }
56     sort(a,a+e,cmp);
57     for(int i=0;i<v;++i){
58         if(isfull(flag,v))
59             break;
60         Union(a[i].begin,a[i].end,father,rank);
61         cout<<"("<<a[i].begin<<","<<a[i].end<<")"<<endl;
62         flag[a[i].begin]=true;
63         flag[a[i].end]=true;
64     }
65     return 0;
66 }
View Code

普里姆

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int INF=1<<30;
 4 const int maxn=110;
 5 typedef struct {
 6     int mp[maxn][maxn];
 7     int number;
 8 }Graph;
 9 void prim(Graph &a)
10 {
11     int min,i,j,k;
12     int adj[maxn],lowcost[maxn];
13     lowcost[0]=0;
14     adj[0]=0;
15     for(int i=1;i<a.number;++i){
16         lowcost[i]=a.mp[0][i];
17         adj[i]=0;
18     }
19     for(int i=1;i<a.number;++i){
20         int min=INF;
21         int j=1,k=0;
22         while(j < a.number)
23         {
24             if( lowcost[j]!=0 && lowcost[j]<min){
25                 min = lowcost[j];
26                 k=j;
27             }
28             j++;
29         }
30         cout<<"("<<adj[k]<<","<<k<<")"<<endl;
31         lowcost[k]=0;
32         for(int j=1;j<a.number;++j){
33             if(lowcost[j]!=0 && a.mp[k][j]<lowcost[j]){
34                 lowcost[j]=a.mp[k][j];
35                 adj[j]=k;
36             }
37         }
38     }
39 }
40 int main()
41 {
42     freopen("in.txt","r",stdin);
43     Graph a;
44     int v,e,x,y,w;
45     cin>>v>>e;
46     a.number=v;
47     for(int i=0;i<v;++i)
48         for(int j=0;j<v;++j)
49         a.mp[i][j]=INF;
50     for(int i=0;i<v;++i)
51         a.mp[i][i]=0;
52     for(int i=0;i<e;++i){
53         cin>>x>>y>>w;
54         a.mp[x][y]=w;
55         a.mp[y][x]=w;
56     }
57     prim(a);
58     return 0;
59 }
View Code

tarjan求强连通分量+缩点

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e4+7;
 4 vector<int> g[maxn];
 5 vector<int> newp[maxn];
 6 int dfn[maxn],low[maxn],sccno[maxn];
 7 int idx=0;
 8 bool visit[maxn];
 9 stack<int> s;
10 void tarjan(int u)
11 {
12     dfn[u]=low[u]=++idx;
13     s.push(u);
14     visit[u]=true;
15     int v;
16     for(int i=0;i<g[u].size();++i){
17         v=g[u][i];
18         if(dfn[v]==0){
19             tarjan(v);
20             low[u]=min(low[u],low[v]);
21         }else if(visit[v])
22             low[u]=min(low[u],dfn[v]);
23     }
24     if(dfn[u]==low[u])
25         do{
26             v=s.top();
27             s.pop();
28             sccno[v]=u;//Ëõµã
29             visit[v]=false;
30         }while(u!=v);
31 }
32 void suodian(int n)
33 {
34     int v,u;
35     for(int i=1;i<=n;++i){
36         for(int j=0;j<g[i].size();++j){
37             u=g[i][j];
38             if(sccno[i]==u)
39                 continue;
40             if(w[u]==0)
41                 continue;
42             if(u!=sccno[u]){
43                 w[sccno[u]]+=w[u];
44                 w[u]=0;
45             }else
46                 newp[sccno[i]].push_back(u);
47         }
48     }
49 }
50 int main()
51 {
52     ios::sync_with_stdio(false);
53     //freopen("in.txt","r",stdin);
54     int n,m,u,v;
55     memset(dfn,0,sizeof(dfn));
56     cin>>n>>m;
57     for(int i=1;i<=n;++i)
58         cin>>w[i];
59     for(int i=1;i<=m;++i){
60         cin>>u>>v;
61         g[u].push_back(v);
62     }
63     for(int i=1;i<=n;++i)
64         sccno[i]=i;
65     tarjan(1);
66     suodian(n);
67     return 0;
68 }
View Code

拓扑排序

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=110;
 4 const int INF=1<<30;
 5 int mp[maxn][maxn]£¬in[maxn];
 6 int cnt=0;
 7 bool clear(int n)
 8 {
 9     for(int i=0;i<n;++i)
10         if(in[i])
11             return false;
12     return true;
13 }
14 void TopSort(int v,int n)
15 {
16     if(clear(n))
17         return ;
18     cnt++;
19     cout<<v<<" ";
20     for(int i=0;i<n;++i){
21         if(i==v)
22             continue;
23         mp[i][v]=INF;
24         if(mp[v][i]!=INF){
25             in[i]--;
26             mp[v][i]=INF;
27             if(in[i]==0)
28                 TopSort(i,n);
29         }
30     }
31 }
32 int main()
33 {
34     int n,m,x,y,w;
35     memset(in,0,sizeof(in));
36     cin>>n>>m;
37     for(int i=0;i<n;++i)
38         for(int j=0;j<n;++j)
39             mp[i][j]=INF;
40     for(int i=0;i<m;++i){
41         cin>>x>>y>>w;
42         mp[x][y]=w;
43         in[y]++;
44     }
45     for(int i=0;i<n;++i){
46         if(in[i]==0){
47             TopSort(i,n);
48             break;
49         }
50     }
51     cout<<endl;
52     if(cnt==n)
53         cout<<"It's AOV"<<endl;
54     else
55         cout<<"It's not AOV"<<endl;
56     return 0;
57 }
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!