1、KMP
int next[2005]; int lena; int lenb; void set_naxt()//子串的next数组 { int i=0,j=-1; next[0]=-1; while(i<lenb) { if(j==-1||b[i]==b[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int kmp() { int i=0,j=0; set_naxt(); while(i<lena) { if(j==-1||a[i]==b[j]) { i++;j++; } else j=next[j]; if(j==lenb) return i-j+1; } return -1; }2、归并排序
void mergesort(int l,int r) { int i,j,k,m; if(l<r) { m=(r+l)>>1; mergesort(l,m); mergesort(m+1,r); k=l; for(i=l,j=m+1; i<=m&&j<=r;) { if(a[i]>a[j]) { b[k++]=a[j++]; //cont+=m-(i-1);//相当于线性交换了这么多次 } else b[k++]=a[i++]; } while(i<=m)b[k++]=a[i++]; while(j<=r)b[k++]=a[j++]; for(i=l; i<=r; i++)a[i]=b[i]; } }3、快速排序
void quicksort(int l,int r) { int i,j,tmp,t; if(l>r)return ; tmp=a[l];i=l,j=r; while(i!=j) { while(a[j]>=tmp&&i<j)j--; while(a[i]<=tmp&&i<j)i++; if(i<j) { t=a[i];a[i]=a[j];a[j]=t; } } a[l]=a[i]; a[i]=tmp; quicksort(l,i-1); quicksort(i+1,r); }4、多重背包(包含01背包,完全背包)
void zoreonepack(int val,int cost) { for(int i=v;i>=cost;i--) { if(dp[i-cost]+val>dp[i]) { dp[i]=dp[i-cost]+val; } } } void completepack(int val,int cost) { for(int i=cost;i<=v;i++) { dp[i]=max(dp[i],dp[i-cost]+val); } } void multipack(int val,int cost,int num) { if(num*cost>=v) { completepack(val,cost); } else { int k=1; while(k<num) { zoreonepack(k*val,k*cost); num-=k;k+=k; } zoreonepack(num*val,num*cost); } }5、二维0-1背包
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; int weight[3405],value[3405],dp[3405][12890]; void solve(int n,int w) { for(int i=1;i<=n;i++) { for(int j=1;j<=w;j++) { if(weight[i]>j) { dp[i][j] = dp[i-1][j];//买不了所以直接继承 } else { dp[i][j]=max(dp[i-1][j-weight[i]]+value[i],dp[i-1][j]); } } } cout<<dp[n][w]<<endl; } int main() { int n,w; while(cin>>n>>w) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { cin>>weight[i]>>value[i]; } solve(n,w); } return 0; }6、哈希表
const int maxn=100000; const int hashh=1000007; struct hashmap { ll a[maxn]; int head[hash]; int next[maxn]; int size; void init() { memset(head,-1,sizeof(head)); size=0; } bool find(ll val) { int tmp=(val%hash+hash)%hash; for(int i=head[tmp];i!=-1;i=next[i]) { if(val==a[i])return true; } return false; } void add(ll val) { int tmp=(val%hash+hash)%hash; if(find(val))return ; a[size]=val; next[size]=head[tmp];//令next指向-1、 head[tmp]=size++; } }h1,h2;7、叉乘
double chacheng(Point p1, Point p2, Point p3) { return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y); }
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; #define mod 10000 typedef struct Matrix { int mat[2][2]; }matrix; matrix A,B; Matrix matrix_mul(matrix a,matrix b)矩阵乘法 { matrix c; memset(c.mat,0,sizeof(c.mat)); int i,j,k; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { for(int k=0;k<2;k++) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; c.mat[i][j]%=mod; } } } return c; } Matrix matrix_quick_power(matrix a,int k)//矩阵快速幂0.0 { matrix b; memset(b.mat,0,sizeof(b.mat)); for(int i=0;i<2;i++) b.mat[i][i]=1;//单位矩阵b while(k) { if(k%2==1) { b=matrix_mul(a,b); k-=1; } else { a=matrix_mul(a,a); k/=2; } } return b; } int main() { int n; while(cin>>n) { if(n==-1)break; A.mat[0][0]=1;A.mat[0][1]=1;//我们通过推论得到的矩阵A A.mat[1][0]=1;A.mat[1][1]=0; B=matrix_quick_power(A,n); cout<<B.mat[0][1]<<endl;//根据推论得出,这个位子上的数据是我们最终需要的数据。 /*for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { cout<<B.mat[i][j]<<" "; } cout<<endl; }*/ } }9、树状数组
int tree[100005];//树 int lowbit(int x)//lowbit { return x&(-x); } int sum(int x)//求和求的是比当前数小的数字之和,至于这里如何实现,很简单:int sum=sum(a[i]); { int sum=0; while(x>0) { sum+=tree[x]; x-=lowbit(x); } return sum; } void add(int x,int c)//加数据。 { while(x<=n) { tree[x]+=c; x+=lowbit(x); } }10、二维树状数组
int lowbit(int x) { return x&(-x); } void update(int x,int y,int d) { int temp=y; while(x<=m) { y=temp; while(y<=m) { a[x][y]+=d; y=y+lowbit(y); } x=x+lowbit(x); } } int getsum(int x,int y) { int sum=0; int temp=y; while(x>0) { y=temp; while(y>0) { sum=sum+a[x][y]; y=y-lowbit(y); } x=x-lowbit(x); } return sum; } update(x+1,y+1,d);
#define lson l,m,rt*2 #define rson m+1,r,rt*2+1 void pushup(int rt) { tree[rt]=tree[rt<<1]+tree[rt<<1|1]; } int Query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { return tree[rt]; } else { int m=(l+r)>>1; int ans=0; if(L<=m) { ans+=Query(L,R,lson); } if(m<R) { ans+=Query(L,R,rson); } return ans; } } void build( int l ,int r , int rt ) { if( l == r ) { scanf("%d",&tree[rt]); return ; } else { int m = (l+r)>>1 ; build(lson) ; build(rson) ; pushup(rt) ; } } void update(int p,int c,int l,int r,int rt)//p阵营c数据. { //printf("%d %d %d %d %d\n",p,c,l,r,rt); if(l==r) { tree[rt]+=c; } else { int m=(l+r)>>1; if(p<=m) update(p,c,lson); else update(p,c,rson); pushup(rt); //printf("sum[%d]:%d\n",rt,tree[rt]); } } int query(int L, int R, int l, int r, int rt, int *pos)//返回位子 { if (L <= l && r <= R) { *pos = posn[rt]; return tree[rt]; } else { int m = (l + r) >> 1; int ret1 = INT_MIN; int ret2 = INT_MIN; int pa, pb; int *pos1 = &pa; int *pos2 = &pb; if (L <= m) { ret1 = query(L, R, lson, pos1); } if (R > m) { ret2 = query(L, R, rson, pos2); } if (ret1 > ret2) { *pos = pa; } else { *pos = pb; ret1 = ret2; } return ret1; } } int pos; printf("%d %d\n", pos, query(1, n, 1, n, 1, &pos));12、线段树2(区间更新很好的模板)
#include<stdio.h> #include<string.h> using namespace std; #define lson l,m,rt*2 #define rson m+1,r,rt*2+1 #define ll long long int ll tree[1212112]; ll flag[1212112]; void pushdown(int l,int r,int rt)//向下维护树内数据 { if(flag[rt])//如果贪婪标记不是0(说明需要向下进行覆盖区间(或点)的值) { int m=(l+r)/2; flag[rt*2]+=flag[rt]; flag[rt*2+1]+=flag[rt]; tree[rt*2]+=(m-l+1)*flag[rt];//千万理解如何覆盖的区间值(对应线段树的图片理解(m-l)+1)是什么意识. tree[rt*2+1]+=(r-(m+1)+1)*flag[rt]; flag[rt]=0; } } void pushup(int rt) { tree[rt]=tree[rt<<1]+tree[rt<<1|1]; } void build( int l ,int r , int rt ) { if( l == r ) { scanf("%lld",&tree[rt]); return ; } else { int m = (l+r)>>1 ; build(lson) ; build(rson) ; pushup(rt) ; return ; } } ll Query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { return tree[rt]; } else { pushdown(l,r,rt); int m=(l+r)>>1; ll ans=0; if(L<=m) { ans+=Query(L,R,lson); } if(m<R) { ans+=Query(L,R,rson); } return ans; } } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R)//覆盖的是区间~ { tree[rt]+=c*((r-l)+1);//覆盖当前点的值 flag[rt]+=c;//同时懒惰标记~! return ; } pushdown(l,r,rt); int m=(l+r)/2; if(L<=m) { update(L,R,c,lson); } if(m<R) { update(L,R,c,rson); } pushup(rt); } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { memset(flag,0,sizeof(flag)); memset(tree,0,sizeof(tree)); build(1,n,1); for(int i=0;i<m;i++) { char s[5]; int x,y; scanf("%s%d%d",s,&x,&y); if(s[0]=='Q') { printf("%lld\n",Query(x,y,1,n,1)); } if(s[0]=='C') { ll c; scanf("%lld",&c); update(x,y,c,1,n,1); } } } }
void creattrie(char *str) { int len=strlen(str); tire *p=root,*q; for(int i=0;i<len;i++) { int id=str[i]-'0'; if(p->next[id]==NULL) { q=(trie *)malloc(sizeof(trie)); q->v=1; for(int j=0;j<maxn;j++) { q->next[j]=NULL; } p->next[id]=q; p=p->next[id]; } else { p->next[id]->v++; p=p->next[id]; } } p->v=-1; } int findtrie(char *str) { int len=strlen(str); trie *p=root; for(int i=0;i<maxn;i++) { int id=str[i]-'0'; p=p->next; if(p==NULL) return 0; if(p->v==-1) { return -1; } } return -1; } int dealTrie(Trie* T) { int i; if(T==NULL) return 0; for(i=0;i<MAX;i++) { if(T->next[i]!=NULL) deal(T->next[i]); } free(T); return 0; }14、做题更实用的字典树
#include<stdio.h> #include<string.h> #include<iostream> #include<stdlib.h> using namespace std; #define maxn 26//只包含小写字母、 typedef struct tree { int flag; tree *next[maxn]; char la[30]; }tree; tree root; void creat(char *str) { int len=strlen(str); tree *p=&root,*q; for(int i=0;i<len;i++) { int id=str[i]-'a'; if(p->next[id]==NULL) { q=(tree *)malloc(sizeof(root)); q->v=1; for(int j=0;j<26;j++) { q->next[j]=NULL; } p->next[id]=q; } else { p->next[id]->v++; } p=p->next[id]; } } int find(char *str) { int len=strlen(str); tree *p=&root; for(int i=0;i<len;i++) { int id=str[i]-'a'; p=p->next[id]; if(p==NULL) return 0; } return p->v; } char str[15]; int i; for(int i=0;i<26;i++) { root.next[i]=NULL; } void Freedom(tree* p) { int i; for(i=0;i<52;i++){ if(p->next[i]!=NULL) Freedom(p->next[i]); } free(p); } Freedom(&root);
void prim() { int i,j,k,min; for(i=2;i<=n;i++) dis[i]=map[1][i]; vis[1]=1; for(i=2;i<=n;i++)//经过N次遍历一定能遍历所有的点 也就是完成了最终目标. { min=inf; for(j=1;j<=n;j++) { if(vis[j]==0 &&dis[j]<min) { min=dis[j]; k=j; } } if(min==inf) break; vis[k]=1; sum+=sqrt(1.0*min);//完成了一次权值加和. for(j=2;j<=n;j++) { if(vis[j]==0 &&dis[j]>map[k][j]) dis[j]=map[k][j]; }//更新最优解. } }16、并查集
int find(int a) { int r=a; while(f[r]!=r) r=f[r]; int i=a; int j; while(i!=r) { j=f[i]; f[i]=r; i=j; } return r; } int find(int x) { return f[x] == x ? x : (f[x] = find(f[x])); } void merge(int a,int b) { int A,B; A=find(a); B=find(b); if(A!=B) f[B]=A; }
#include<stdio.h> #include<string.h> using namespace std; int f[1000010]; int sum[1000010]; int find(int x) { if(x!=f[x]) { int pre=f[x];//pre是x的一个父节点。 f[x]=find(f[x]);//递归找祖先。 sum[x]+=sum[pre]; } return f[x]; } int main() { int n; while(~scanf("%d",&n)) { for(int i=0;i<=n;i++) { f[i]=i; sum[i]=0; } int op; while(n--) { scanf("%d",&op); if(op==1) { int x,y,val; scanf("%d%d%d",&x,&y,&val); int X=find(x); int Y=find(y); if(X!=Y) { sum[Y]=val-sum[y]+sum[x]; f[Y]=X; } } else { int x,y; scanf("%d%d",&x,&y); int X=find(x); int Y=find(y); if(X!=Y) { printf("?\n"); } else { printf("%d\n",sum[y]-sum[x]); } } } } }
#include<stdio.h> #include<string.h> using namespace std; const int maxn = 505; int map[maxn][maxn]; //图的数组. int vis[maxn]; //标记数组. int pri[maxn]; int k,m,n; int find(int x) { for(int i=1;i<=m;i++) { if(vis[i]==0&&map[i][x]) { vis[i]=1; if(pri[i]==-1||find(pri[i])) { pri[i]=x; return 1; } } } return 0; } int main() { while(~scanf("%d",&k)) { if(k==0)break; scanf ("%d%d", &m, &n); memset (map, 0, sizeof (map)); memset (pri, -1, sizeof (pri)); for(int i=0;i<k;i++) { int a,b; scanf("%d%d",&a,&b); map[a][b]=1; } int output=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(find(i)) output++; } printf("%d\n",output); } }
int bfs(int x) { queue<int >s; int one=0; int two=0; s.push(x); color[x]=1; one++; while(!s.empty()) { int u=s.front(); s.pop(); for(int i=0;i<map[u].size();i++) { int v=map[u][i]; if(color[v]) { if(color[v]==color[u]) { return 0; } } else { color[v]=3-color[u]; if(color[v]==1) { one++; } else { two++; } s.push(v); } } } ans+=max(one,two); return 1; }
#include<stdio.h> #include<string.h> using namespace std; int head[100000]; struct EdgeNode { int to; int w; int next; }e[100000]; int n,u,v,w,m; int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&w); e[i].to=v; e[i].w=w; e[i].next=head[u]; head[u]=i; } for(int i=1;i<=n;i++) { printf("from: %d ",i); for(int k=head[i];k!=-1;k=e[k].next) { printf("to:%d quanzhi:%d ",i,e[k].to,e[k].w); } printf("\n"); } }
struct EdgeNode { int to; int w; }; vector<EdgeNode>map[maxn]; int main() { int i,j,w,n,m,u,v; EdgeNode e; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&w); e.to=v; e.w=w; map[u].push_back(e); } printf("yes\n"); for(int i=1;i<=n;i++) { printf("i: %d ",i); for(int j=0;j<map[i].size();j++) { printf("j: %d w: %d ",map[i][j].to,map[i][j].w); } printf("\n"); } }
#include<stdio.h> #include<string.h> using namespace std; int map[1000][1000]; int degree[1000]; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { memset(map,0,sizeof(map)); memset(degree,0,sizeof(degree)); if(n==0&&m==0)break; for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); if(map[x][y]==0) { map[x][y]=1; degree[y]++; } } int cont=0; int flag=0; while(1) { int v; int ok=1; for(int i=0;i<n;i++) { if(degree[i]==0){v=i;ok=0;break;} } if(ok==1){flag=1;break;} degree[v]=-1; cont++; if(cont==n)break; for(int i=0;i<n;i++) { if(map[v][i]==1) { map[v][i]=-1; degree[i]--; } } } if(flag==1) { printf("NO\n"); } else printf("YES\n"); } }
#include <stdio.h> #include <iostream> #include <string.h> #include <queue> using namespace std; const int N=1005; int pre[N]; //保存增广路径上的点的前驱顶点 bool vis[N]; int map[N][N]; int s,t; //s为源点,t为汇点 int n,m; bool bfs() { int i,cur; queue<int >q; memset(pre,0,sizeof(pre)); memset(vis,0,sizeof(vis)); vis[s]=true; q.push(s); while(!q.empty()) { cur=q.front(); q.pop(); if(cur==t)return true; for(int i=1;i<=n;i++) { if(vis[i]==0&&map[cur][i]) { q.push(i); pre[i]=cur; vis[i]=true; } } } return false; } int Max_Flow() { int ans=0; while(1) { if(!bfs())return ans; int Min=0x3f3f3f3f; for(int i=t;i!=s;i=pre[i]) { Min=min(Min,map[pre[i]][i]); } for(int i=t;i!=s;i=pre[i]) { map[pre[i]][i]-=Min; map[i][pre[i]]+=Min; } ans+=Min; } } http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html24、bellman最短路
#include<stdio.h> #include<string.h> #include<stdlib.h> using namespace std; int dis[121212]; int u[121212]; int v[121212]; int w[121212]; int main() { int n,m; int check; while(~scanf("%d%d",&n,&m)) { if(n==0||m==0)break; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u[i],&v[i],&w[i]); } for(int i=1;i<=n;i++) { dis[i]=0x1f1f1f1f; } dis[1]=0; for(int k=1;k<=n-1;k++)//最多遍历点的次数. { check=0; for(int i=1;i<=m;i++) { if(dis[v[i]]>dis[u[i]]+w[i]) { dis[v[i]]=dis[u[i]]+w[i]; check=1; } if(dis[u[i]]>dis[v[i]]+w[i]) { dis[u[i]]=dis[v[i]]+w[i]; check=1; } } if(check==0)break; } int flag=0;//标记是否有负权回路... for(int i=0;i<=m;i++) { if(dis[v[i]]>dis[u[i]]+w[i]) { dis[v[i]]=dis[u[i]]+w[i]; flag=1; } if(dis[u[i]]>dis[v[i]]+w[i]) { dis[u[i]]=dis[v[i]]+w[i]; flag=1; } } if(flag==1){printf("0\n");continue;} printf("%d\n",dis[n]); } }25、dij最短路
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<stdlib.h> using namespace std; #define MAX(a,b) (a > b ? a : b) #define MIN(a,b) (a < b ? a : b) #define MAXN 10000001 #define INF 1000000007 int w[250][250]; int d[250]; int vis[250]; int n; void dijkstra(int s) { d[s]=0; for(int k=0;k<n;k++) { int m=INF; for(int i=0;i<n;i++) { if(!vis[i] && d[i]<=m) m=d[s=i]; } vis[s] = 1; for(int i=0;i<n;i++) { d[i]=MIN(d[i],d[s]+w[s][i]); } } } int main() { int m; while(~scanf("%d%d",&n,&m) && (n || m)) { memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) { d[i]=INF; for(int j=0;j<n;j++) { w[i][j]=INF; } } int a,b,x; for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&x); w[a-1][b-1] = w[b-1][a-1] = x; } dijkstra(0); printf("%d\n",d[n-1]); } return 0; }26、floyd求最小环
int ans=0x1f1f1f1f; for(int i=0;i<n;i++) { for(int j=0;j<i;j++) { for(int k=j+1;k<i;k++) { ans=min(ans,map[j][k]+dis[k][i]+dis[i][j]); } } for(int j=0;j<n;j++) { for(int k=0;k<n;k++) { map[j][k]=min(map[j][k],map[j][i]+map[i][k]); } } }27、spfa
int SPFA(int s) { int i; bool visit[N] = {false}; int front = 0, rear = 1; memset(queue,0,sizeof(queue)); for(i=1;i<=n;i++) d[i] = MAX; queue[front] = s; visit[s] = true; d[s] = 0; while(front<rear) { int u = queue[front]; visit[u] = false; for(int i=1; i<=n; i++) { if (d[i]>d[u]+ edges[u][i]) { d[i]= d[u]+edges[u][i]; if( !visit[i] ) { visit[i] = true; queue[rear++] = i; } } } front++; } return 0; }28、更习惯实用的dij
void Dij() { int i,j,k,v,tmp; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++)//这里等号很魔怔 d[i]=w[1][i];//当然是要起点开始走. d[1]=0; vis[1]=1; for(i=1;i<=n;i++)//为了连接多少点的控制.//这里等号一样魔怔 { tmp=N; for(j=1;j<=n;j++) { if(tmp>d[j]&&!vis[j]) { tmp=d[j]; v=j; } }//每次选中的都是距离起点最近的点.v vis[v]=1; for(k=1;k<=n;k++) { if(!vis[k])//然后松弛. d[k]=min(d[k],d[v]+w[v][k]); } } }
#include<stdio.h> #include<string.h> #include<map> #include<iostream> #include<vector> #include<queue> const int maxn=30003; const int INF=0x1f1f1f1f; int n,m; using namespace std; struct Edge { int from,to,dist; Edge(int u,int v,int d):from(u),to(v),dist(d) {} }; string s; string e; vector<Edge>edges;//存储边的结点信息 vector<int>G[maxn];//邻接表 bool done[maxn]; //标记是否访问过 int d[maxn]; //距离数组 map<string,int>cnt;//映射成节点编号 struct heapnode //用于优先队列自定义 { int d,u; bool operator <(const heapnode rhs) const { return d > rhs.d; } heapnode(int dd,int uu):d(dd),u(uu) {} }; void init()//初始化必不可少 { for(int i=0; i<n; i++) G[i].clear(); edges.clear(); } void dij( int s) { priority_queue<heapnode>Q; for(int i=0; i<=n; i++)//初始化距离数组 d[i]=INF; d[s]=0; memset(done ,0,sizeof(done)); Q.push( heapnode(0,s) ); while(!Q.empty()) { heapnode x = Q.top(); Q.pop(); int u=x.u; if(u==cnt[e]) { printf("%d\n",x.d); break; } if(done[u])continue; done[u] = true; for(int i=0; i<G[u].size(); i++) { Edge& e=edges[G[u][i]];//取出来一条邻接边 if(d[e.to]>d[u]+e.dist) { d[e.to] = d[u] + e.dist; Q.push((heapnode(d[e.to],e.to))); } } } } void addedge(int from,int to,int dist) { edges.push_back(Edge(from,to,dist)); int m = edges.size(); G[from].push_back(m-1); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { int t=1; int ans=0; string str; init(); for(int i=0; i<n; i++) { cin>>str; cnt[str]=t++; } for(int i=0; i<m; i++) { string str2; int x; cin>>str>>str2>>x; addedge(cnt[str],cnt[str2],x); addedge(cnt[str2],cnt[str],x); } cin>>s>>e; dij(cnt[s]); s.clear(); e.clear(); cnt.clear(); } return 0; }
#define INF 0x7fffffff double x[1000]; double y[1000]; double w[1000][1000]; int flag[1000];//判断是否在有向环里边的缩点 int vis[1000]; int pre[1000]; int n,m; void init()//不能少了初始化的内容 { memset(vis, 0, sizeof(vis)); memset(flag, 0, sizeof(flag)); for(int i=0; i<=n; i++) { w[i][i] = INF; for(int j=i+1; j<=n; j++) w[i][j]=w[j][i]=INF; } } double directed_mst(int u)//u表示根节点 { double ans=0; memset(vis, 0, sizeof(vis)); while(true) { //求最短弧集合E for(int i=1; i<=n; i++)if(i!=u&&!flag[i]) { w[i][i]=INF, pre[i] = i; for(int j=1; j<=n; j++)if(!flag[j] && w[j][i]<w[pre[i]][i]) { pre[i] = j; } if(pre[i]==i)return -1;//也可以用dfs预处理判断凸的连通 } //判断E是否有环 int i; for(i=1; i<=n; i++) { if(i!=u&&!flag[i]) { int j=i, cnt=0; while(j!=u && pre[j]!=i && cnt<=n) j=pre[j], ++cnt; if(j==u || cnt>n) continue; //最后能找到起点(根)或者是走过的点已经超过了n个,表示没有有向环 break; } } if(i>n) { for(int i=1; i<=n; i++)if(i!=u && !flag[i]) ans+=w[pre[i]][i]; return ans; } //有环,进行收缩,把整个环都收缩到一个点i上。 int j=i; memset(vis, 0, sizeof(vis)); do { ans += w[pre[j]][j], j=pre[j], vis[j]=flag[j]=true;//对环内的点标记,并且直接对环的权值进行加和记录,在最后找到最小树形图之后就不用展开收缩点了 } while(j!=i); flag[i] = false; // 环缩成了点i,点i仍然存在 //收缩点的同时,对边权值进行改变 for(int k=1; k<=n; ++k)if(vis[k]) // 在环中点点 { for(int j=1; j<=n; j++)if(!vis[j]) // 不在环中的点 { if(w[i][j] > w[k][j]) w[i][j] = w[k][j]; if(w[j][k]<INF && w[j][k]-w[pre[k]][k] < w[j][i]) w[j][i] = w[j][k] - w[pre[k]][k]; } } } return ans; }
struct zuobiao { int x,y,output; friend bool operator <(zuobiao a,zuobiao b) { return a.output>b.output; } }now,nex; priority_queue<zuobiao>s; struct cmp{ bool operator ()(int &a,int &b){ return a>b;//最小值优先 } }; priority_queue<int,vector<int>,cmp>s;//最小值优先
32、gcd
int gcd(int x,int y) { return y==0?x:gcd(y,x%y); } int gcd(int x,int y) { if(x%y==0)return y; else return gcd(y,x%y); }
#define mod 5645618765 const int MAXN = 100; // 组合上限 long long int c[MAXN][MAXN]; // 组合数 void GetGroup() { c[0][0] = c[1][0] = c[1][1] = 1; for (int i=2; i<MAXN; ++i) { c[i][0] = 1; for (int j=1; j<=i; ++j) c[i][j] = (c[i-1][j] + c[i-1][j-1])%mod; // 求模,防止结果过大 } return ; } CMN=m!/n!(m-n)!
34、phi函数,欧拉降幂模板
long long eular(long long n) { long long ans = n; int q = (int)sqrt(n); for (int i=2; i<=q; i++) { if (n % i == 0) { ans -= ans / i; while (n % i == 0) { n /= i; } } } if (n > 1) { ans -= ans / n; } return ans; }
#include<stdio.h> #include<string.h> using namespace std; int Scan() { int res = 0, ch, flag = 0; if((ch = getchar()) == '-') //判断正负 flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9' ) res = res * 10 + ch - '0'; return flag ? -res : res; } int main() { int n=Scan(); printf("%d\n",n); }
int judge(date &b) { int tmp=0; for(int i=0;i<b.len;i++) { tmp=(tmp*c+b.a[i])%n; } return tmp; }37、分形
#include<stdio.h> #include<math.h> #include<string.h> #include<iostream> using namespace std; char a[3500][3500]; int vis[7][7]; int n; char tmp; void dayin(int cur,int x,int y) { if(cur==1) { a[x][y]=tmp; return ; } int ss=pow(n,cur-2); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(vis[i][j]==1) { dayin(cur-1,x+i*ss,y+j*ss); } } } return ; } int main() { while(~scanf("%d",&n)) { if(n==0)break; getchar(); memset(vis,0,sizeof(vis)); memset(a,'\0',sizeof(a)); for(int i=0;i<n;i++) { gets(a[i]); for(int j=0;j<n;j++) { if(a[i][j]!=' '&&a[i][j]!='\0') { vis[i][j]=1; tmp=a[i][j]; } } } memset(a,' ',sizeof(a)); int k; scanf("%d",&k); int s=pow(n,k);//最大范围s、 dayin(k+1,0,0); for(int i=0;i<s;i++) { a[i][s]='\0'; puts(a[i]); } } }