二刷 P3366 【模板】最小生成树 Kruskal模板 背诵
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define MAXN 5005
#define MAXV 200005
using namespace std;
struct node{int u,v,w;
}edge[MAXV];int fa[MAXN];int n,m,ans=0;
int find(int x){if(x==fa[x]) return x;else return fa[x]=find(fa[x]);
}
void merge(int u,int v){fa[find(u)]=find(v);
}
bool cmp(node a,node b){return a.w<b.w;
}
void Kruskal(){sort(edge+1,edge+m+1,cmp);int line=0;for(int i=1;i<=m;i++){int to=edge[i].v;int f=edge[i].u;if(find(to)==find(f)) continue;merge(to,f);line++;ans+=edge[i].w;if(line==n-1){printf("%d",ans);return;}}printf("orz");return;//遍历完所有边 也选不出n-1条边 说明不连通
}
int main(){scanf("%d%d",&n,&m);int id=0;for(int i=1;i<=m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c); edge[++id].u=a;edge[id].v=b;edge[id].w=c;}for(int i=1;i<=n;i++) fa[i]=i;Kruskal();return 0;
}
二刷 P3366 【模板】最小生成树 Prim算法模板背诵
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
//Prim最小生成树模板题
#define MAXN 5005
#define MAXV 400005
#define INF 0x7fffffff
using namespace std;
struct node{int to;int weight;int next;
}edge[MAXV];int x=1;int head[MAXN];int n,m;
int dis[MAXN];bool visited[MAXN];int ans=0;
void add(int u,int v,int w){edge[x].to=v;edge[x].weight=w;edge[x].next=head[u];head[u]=x++;
}
void init(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);add(b,a,c);//无向图构建 }fill(visited,visited+MAXN,0);fill(dis,dis+MAXN,INF);
}
struct priority{int id;int dist;friend bool operator < (priority a,priority b){return a.dist>b.dist;//小堆 }
};
priority_queue<priority> q;
void Prim(){dis[1]=0;q.push(priority{1,dis[1]});while(!q.empty()){priority tmp = q.top();q.pop();int tmpid=tmp.id;if(!visited[tmpid]){visited[tmpid]=1;ans+=dis[tmpid];for(int i=head[tmpid];i;i=edge[i].next){int targ=edge[i].to;int w = edge[i].weight;dis[targ]=min(dis[targ],w);if(!visited[targ]) q.push(priority{targ,dis[targ]});}}}for(int i=1;i<=n;i++)if(!visited[i]){printf("orz");return;}printf("%d",ans);
}
int main(){init();Prim();return 0;
}
二刷 P1443 马的遍历 BFS广搜 经典背诵
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<queue>
//#define inf 0x3f3f3f3f
using namespace std;
int n,m,x,y;
int pan[405][405];
int xx[]={0,-1,-2,-1,-2,1,2,1,2};
int yy[]={0,2,1,-2,-1,2,1,-2,-1};
queue<pair<int,int> >q;
//区分数学里(x,y)坐标 和数组中的[x][y]
void bfs(){pan[x][y]=0;q.push(make_pair(x,y));while(!q.empty()){int x0=q.front().first,y0=q.front().second;q.pop();if(x0<1||x0>n||y0<1||y0>m) continue;//错因 改半天 因为n和m顺序写反了可还行 for(int i=1;i<=8;i++){if(pan[x0+xx[i]][y0+yy[i]]==-1)pan[x0+xx[i]][y0+yy[i]]=pan[x0][y0]+1,q.push(make_pair(x0+xx[i],y0+yy[i])); }}
}
int main(){scanf("%d%d%d%d",&n,&m,&x,&y);fill(pan[0],pan[0]+405*405,-1);bfs();for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) printf("%d ",pan[i][j]);printf("\n"); }return 0;
}
二刷 P3371 【模板】单源最短路径(弱化版) Dijkstra模板背诵
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 20005
#define MAXV 1000005
#define INF 0x3f3f3f3f
#include<queue>
using namespace std;
struct node{int to;int weight;int next;
}edge[MAXV];int head[MAXN];int x=1;bool visited[MAXN];int dis[MAXN];
int n,m,s;
void add(int u,int v,int w){edge[x].to=v;edge[x].weight=w;edge[x].next=head[u];head[u]=x++;
}
void init(){scanf("%d%d%d",&n,&m,&s);for(int i=1;i<=m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}fill(visited,visited+MAXN,0);fill(dis,dis+MAXN,INF);
}
struct priority{int id;int dist;friend bool operator < (priority a,priority b){return a.dist>b.dist;//小堆 }
};
priority_queue<priority> q;
void Dijkstra(){dis[s]=0;q.push(priority{s,dis[s]});while(!q.empty()){priority tmp=q.top();q.pop();int tmpid=tmp.id;if(!visited[tmpid]){visited[tmpid]=1;for(int i=head[tmpid];i;i=edge[i].next){int targ=edge[i].to;if(dis[targ]>dis[tmpid]+edge[i].weight){dis[targ]=dis[tmpid]+edge[i].weight;if(!visited[targ]) q.push(priority{targ,dis[targ]});}}}}
}
int main(){init();Dijkstra();for(int i=1;i<=n;i++){if(dis[i]!=INF) printf("%d ",dis[i]);else cout<<0x7fffffff<<" ";//有符号数 32比特 占用31比特为数值 则最大为2的31次方-1为最大数值 0111111111111111 } return 0;
}
二刷 P1123 取数游戏 dfs深搜经典背诵
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int T,n,m;int a[8][8];int con[8][8];//用于统计位置的空闲
int maxs=0;int tmpmax=0;
int xx[]={0,-1,-1,-1,0,0,1,1,1};
int yy[]={0,1,0,-1,1,-1,1,0,-1};
void dfs(int x,int y){if(x>n){maxs=max(maxs,tmpmax);return;}if(y==m) dfs(x+1,1); else dfs(x,y+1);if(con[x][y]==0){for(int i=1;i<=8;i++) con[x+xx[i]][y+yy[i]]++;tmpmax+=a[x][y];if(y==m) dfs(x+1,1); else dfs(x,y+1);for(int i=1;i<=8;i++) con[x+xx[i]][y+yy[i]]--;tmpmax-=a[x][y];//回溯 }
}
int main(){scanf("%d",&T);for(int t=1;t<=T;t++){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);fill(con[0],con[0]+8*8,0);tmpmax=0,maxs=0;dfs(1,1);printf("%d\n",maxs);}return 0;
}
二刷 P1048 [NOIP2005 普及组] 采药 动态规划背包01问题
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define MAXN 1005
using namespace std;
//01背包问题模板
int T,M;int times[MAXN];int values[MAXN];
int dp[MAXN][MAXN];//dp[i][j] 考虑前i个物品,时间容量为j时 最大价值
//bool visited[MAXN];int maxvalue=0;
int dp2[MAXN];
void init(){scanf("%d%d",&T,&M);for(int i=1;i<=M;i++) scanf("%d%d",×[i],&values[i]);for(int i=0;i<=T;i++) dp[0][i]=0;for(int i=0;i<=M;i++) dp[i][0]=0; //fill(visited,visited+MAXN,0);
}
void GetDp2(){ //不需要记录选项的时候 可以直接用一维数组表示重量部分T 物品部分M用循环替代 减少空间复杂度dp2[0]=0;for(int i=1;i<=M;i++)for(int j=T;j>=0;j--){if(times[i]>j) dp2[j]=dp2[j];else dp2[j]=max(dp2[j],dp2[j-times[i]]+values[i]); }
}
void GetDp(){for(int i=1;i<=M;i++)for(int j=1;j<=T;j++){if(j<times[i]) dp[i][j]=dp[i-1][j];else dp[i][j]=max(dp[i-1][j],dp[i-1][j-times[i]]+values[i]);}
}
int main(){init();//GetDp();GetDp2();//int tmp=M;int bagleft=T;
// while(M>=0){//获得选项的方法 如果只要结果 就不需要visited和这个步骤
// if(dp[M][bagleft]!=dp[M-1][bagleft]){
// visited[M]=1;maxvalue+=times[M];
// bagleft-=times[M];
// }
// M--;
// }//printf("%d",maxvalue);//printf("%d",dp[M][T]);printf("%d",dp2[T]);return 0;
}
二刷 KMP算法 next版本背诵专用 匹配所有位置
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
//KMP算法背诵版 匹配所有位置
int main(){string a,b;//a为初试串 b为目标串getline(cin,a);getline(cin,b);int len=a.length();int next[len+1];//接下来获得next数组int i=0,j=-1;next[0]=-1;while(i<=int(b.length())){if(j==-1||b[i]==b[j]) ++i,++j,next[i]=j;else j=next[j];}//接下来进行匹配 i=0,j=0;while(i<=int(a.length())&&j<=int(b.length())){if(j==-1||a[i]==b[j]) ++i,++j;else j=next[j];if(j>=int(b.length())) j=next[j],printf("位置是%d\n",i-int(b.length())+1);}return 0;
}
★★★P1629 邮递员送信 Flyod算法实现 可背 vctor邻接表 多源最短路径
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define INF 0x3f3f3f3f
#include<vector>
using namespace std;
//Flyod算法模板改(这题用Dijkstra更合适 仅为了测试Flyod) 正向为单源最短 回来是多源最短
vector<vector<int>>cost;//代价矩阵 邻接表存储图
//vector<vector<int>>path;//路径矩阵
//洛谷 c++11 o2优化 AC
int n,m,ans=0;
void Flyod(){for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){if(cost[i][k]!=INF&&cost[k][j]!=INF&&cost[i][j]>cost[i][k]+cost[k][j]){cost[i][j]=cost[i][k]+cost[k][j];//path[i][j]=k;}}
}
int main(){scanf("%d%d",&n,&m);cost.resize(n+1,vector<int>(n+1,INF)); //resize方法 v.resize(n) 将v的大小改成n v.resize(n,value) 将v的大小改成n 且元素为value for(int i=1;i<=m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);//cost[a][b]=c;//单行路 cost[a][b]=min(cost[a][b],c);}for(int i=1;i<=n;i++) cost[i][i]=0; Flyod();for(int i=2;i<=n;i++) ans=ans+cost[1][i]+cost[i][1];printf("%d",ans);return 0;
}
二刷 P1308 [NOIP2011 普及组] 统计单词数
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
string a,b;
int main(){getline(cin,a);getline(cin,b);int ans=0;for(int i=0;i<a.length();i++) a[i]=tolower(a[i]);for(int j=0;j<b.length();j++) b[j]=tolower(b[j]);a=' '+a+' ';b=' '+b+' ';if(b.find(a)==string::npos){printf("-1");return 0;}int tmp1=b.find(a);int tmp2=tmp1;while(tmp2!=string::npos){ans++;tmp2=b.find(a,tmp2+1);}printf("%d %d",ans,tmp1);return 0;
}
二刷 NUST 15-T7 训练map+set+vector容器的使用
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>//至少的两个元素
#include<set>//一个元素 也可以用pair变成两个
#include<vector>
using namespace std;
bool cmp(pair<int,int> a,pair<int,int> b){return a.second>b.second;//递减排序
}
int main(){//set<pair<int,int>> a;map<int,int> mp;while(1){int x;scanf("%d",&x);if(x==-1) break;mp[x]++;}//map不可以排序 用vector//map的访问可以直接用数组方式 而pair的访问是.first 和.second //使用到迭代器以后 访问一律使用->first和->second printf("各元素及其出现次数:\n");for(map<int,int>::iterator a=mp.begin();a!=mp.end();a++){printf("%d:%d",a->first,a->second);a++;if(a!=mp.end()) printf(",");a--;}vector<pair<int,int> >s;for(map<int,int>::iterator a=mp.begin();a!=mp.end();a++)s.push_back(make_pair(a->first,a->second));//接下来 放入vector后进行排序 按照次数从大到小排序 sort默认是递增 而堆排序默认是递减sort(s.begin(),s.end(),cmp);printf("\n排序结果:\n");for(vector<pair<int,int>>::iterator a=s.begin();a!=s.end();a++){printf("%d:%d",a->first,a->second);if(a+1!=s.end()) printf(",");}return 0;
}