持续更新
STL
vector
vector<int> vec1
vector<vector<int> > vec2(n,vector<int>(m,0))//二维
vector<int> vec2[1000]//也是二维
vec.push_back()
vec.pop_back()
vec.size()
vec[i]
vector<int>().swap(vec)
vec.empty()
vec.begin(),vec.end()
限定空间大小
int k;
cin>>k;
a.resize(k);
初始化
for(vector<int>::iterator it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
排序
sort(a.begin(),a.end());
queue
队列,先进先出
que.size()
que.push()
que.pop()
que.top()
que.front()
que.empty()
初始化(优先队列)
#include<iostream>
#include<queue>
using namespace std;
int main(){
priority_queue<int,vector<int>,/*less<int>*/greater<int> > que;
que.push(7);
que.push(5);
que.push(-1);
cout<<que.size()<<endl;
while(!que.empty()){
cout<<que.top()<<" ";
que.pop();
}
cout<<endl;
return 0;
}
结合结构体元素
#include<queue>
#include<iostream>
using namespace std;
struct node{
int x,y;
bool operator <(const node &b)const{
return this->x>b.x;//>从小到大;<从大到小
}
};
int main(){
priority_queue<node> que;
que.push((node){1,5});
que.push((node){2,3});
while(!que.empty()){
cout<<que.top().x<<endl;
que.pop();
}
return 0;
}
map
1,其基本单位(节点)为pair类型,就是必须有实值(value)和键值。pair的第一元素为键值(通过.first 或->first访问),第二元素为实值(通过.second 或者->second访问)
2,map不容许有相同的键值
3,map中的所有元素(value)都根据键值(key)被自动排序。
4,键值不可以被修改
map<string,int> p
p.insert("china",1)
p["china"]=1
p.count("china")
p.erase("china")
p.size()
p.clear()
输出顺序按照字典序
#include<iostream>
#include<map>
#include<string>
#include<utility>
using namespace std;
int main(){
map<string,int> dict;
dict.insert(make_pair("Tom",1));
dict.insert(make_pair("Tom",2));//不会改变Tom的指向
dict.insert(make_pair("Mary",1));
dict.insert(make_pair("Jone",2));
dict["Tom"]=1;
dict["Mary"]=2;//这样可以修改指向
dict["Jone"]=2;//两种构造是一样的
for(map<string,int>::iterator it=dict.begin();it!=dict.end();it++){
cout<< it->first<<"->"<<it->second<<endl;
}
return 0;
}
map套set
set
存储不重复的元素。set中的元素都是唯一的,重复的元素不会被插入。
自动排序。set中的元素会自动按照一定的顺序进行排序,例如从小到大或从大到小排序(默认升序)。
快速查找。由于set内部是使用红黑树实现的,查找元素的时间复杂度为O(log n),因此set可以在大量数据中快速查找元素。
动态插入和删除元素。set支持动态地插入和删除元素,因此在需要动态维护元素集合的场景中非常有用。
#include<set>
set<string> set;
set.insert("china")
set.erase("china")
set.count("china")集合中是否存在china
for(set<string>::iteraor it=set.begin();it!=set.end();it++){
cout<<*it<<endl;
}
set.clear() 清空
结合结构体,重载运算符
#include<iostream>
#include<set>
using namespace std;
struct Node {
int x, y;
bool operator<(const Node &rhs) const {
if (x == rhs.x) {
return y < rhs.y; // 如果x相等,基于y进行比较
} else {
return x < rhs.x; // 否则基于x进行比较
}
}
};
int main() {
set<Node> mySet; // 使用set存储Node对象
Node node1{1, 2};
Node node2{3, 4};
mySet.insert(node1); // 插入节点到集合中
mySet.insert(node2);
for (set<Node>::iterator it=mySet.begin();it!=mySet.end();it++ ){ // 输出集合中的节点
cout << "(" << it->x << ", " << it->y << ")" << endl; // 修改这里
}
return 0;
}
快速排序
void QuickSort(int array[], int low, int high) {
int i = low;
int j = high;
if(i >= j) {
return;
}
int temp = array[low];
while(i != j) {
while(array[j] >= temp && i < j) {
j--;
}
while(array[i] <= temp && i < j) {
i++;
}
if(i < j) {
swap(array[i], array[j]);
}
}
//将基准temp放于自己的位置,(第i个位置)
swap(array[low], array[i]);
QuickSort(array, low, i - 1);
QuickSort(array, i + 1, high);
}
贪心
区间问题:一般按左端点,右端点,左右端点排序
Huffuman树
回文串
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
样例输入
5
mamad
样例输出
3
#include<iostream>
#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int main(){
int n,flag=0,swap_cnt=0;
//n个字母,判断条件,交换次数
cin>>n;
string str;
cin>>str;
for(int i=0;i<n-1;i++){
for(int j=n-1;j>=i;j--){
if(j==i){//从右一直到左都没有匹配
if(flag==1||str.size()%2==0){//没有匹配的偶数个字母不可能
cout<<"Impossible"<<endl;
return 0;
}
flag=1;
swap_cnt+=str.size()/2-i;//将最左的无法匹配的字母移到中间的次数,奇数个字母
}else if(str[i]==str[j]){//将其移到对应位置的次数
for(int k=j;k<n-1;k++){
swap(str[k],str[k+1]);
swap_cnt++;
}
n--;//对应好一个就不管右边,外层循环i++后不管左边
break;
}
}
}
cout<<swap_cnt<<endl;
return 0;
}
动态规划
最大子段和
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=0x7fffffff;
int num[101];
int main(){
int N;
cin>>N;
for(int i=0;i<N;i++){
cin>>num[i];
}
int ans=-inf;
for(int i=0;i<N;i++){
ans=max(ans,num[i]);
}
if(ans<=0){
cout<<ans<<endl;
}else{
int sum=0;
for(int i=0;i<N;i++){
if(sum+num[i]<0){
sum=0;
}else{
sum+=num[i];
}
ans=max(ans,sum);
}
}
cout<<ans<<endl;
return 0;
}
最长上升子序列(LIS)
#include<iostream>
#include<cstring>
using namespace std;
int dp[101],a[101],n;
int LIS(){
int ans=0;
for(int i=1;i<=n;i++){
dp[i]=1;
for(int j=1;j<i;j++){
if(a[j]<a[i]){
dp[i]=max(dp[i],dp[j]+1);
}
}
ans=max(ans,dp[i]);
}
return ans;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
cout<<LIS()<<endl;
return 0;
}
最长公共子序列
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int dp[110][110];
int main(){
string a,b;
memset(dp,0,sizeof(dp));
cin>>a>>b;
int lena=a.size();
int lenb=b.size();
for(int i=1;i<=lena;i++){
for(int j=1;j<=lenb;j++){
if(a[i-1]==b[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
cout<<dp[lena][lenb]<<endl;
return 0;
}
字符串修改匹配
背包问题
0-1背包
#include<iostream>
using namespace std;
int dp[21][1010];
int w[21],c[21];
int main(){
int N,V;
cin>>N>>V;
for(int i=1;i<=N;i++){
cin>>w[i]>>c[i];
}
for(int i=1;i<=N;i++){
for(int j=0;j<=V;j++){
if(j>=c[i]){
dp[i][j]=max(dp[i-1][j-c[i]]+w[i],dp[i-1][j]);//选
} else{//不选
dp[i][j]=dp[i-1][j];
}
}
}
cout<<dp[N][V]<<endl;
return 0;
}
优化空间一维的0-1背包
#include<iostream>
#include<cstring>
using namespace std;
int dp[1010];
int w[21],c[21];
int main(){
int N,V;
cin>>N>>V;
for(int i=1;i<=N;i++){
cin>>w[i]>>c[i];
}
for(int i=1;i<=N;i++){
for(int j=V;j>=c[i];j--){
dp[j]=max(dp[j-c[i]]+w[i],dp[j]);
}
}
cout<<dp[V]<<endl;
return 0;
}
#include<iostream>
#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int main() {
int n=0;
cin>>n;
vector<int> v(n);
for(int i=0;i<n;i++){
cin>>v[i];
}
sort(v.begin(),v.end());
//s用来保存已经可以称出的重量
set<int> s;
s.insert(v[0]);//一定取第一个元素
s.insert(0);
for(int i=1;i<n;i++){//逐个取出元素
vector<int> tmp;
set<int>::iterator it;
//找到用新砝码可以称出的重量
for(it=s.begin();it!=s.end();it++){
tmp.push_back(v[i]+(*it));
tmp.push_back(abs(v[i]-(*it)));
}
//将新砝码可称出的重量放到集合中
for(int i=0;i<tmp.size();i++){
s.insert(tmp[i]);
}
}
cout<<s.size()-1;
return 0;
}
完全背包
#include<iostream>
#include<cstring>
using namespace std;
int dp[21][1010];
int w[21],c[21],n[21];
int main(){
int N,V;
cin>>N>>V;
for(int i=1;i<=N;i++){
cin>>w[i]>>c[i]>>n[i];
}
for(int i=1;i<=N;i++){
for(int j=0;j<=V;j++){
for(int k=0;k<=n[i];k++){
if(j>=c[i]*k){
dp[i][j]=max(dp[i-1][j-c[i]*k]+w[i]*k,dp[i][j]);
}
}
}
}
cout<<dp[N][V]<<endl;
return 0;
}
DP
共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。
#include<stdio.h>
#include<math.h>
int main()
{
int n,m;
scanf("%d%d",&n,&m);
double p=1.0/n;
double dp[m+1][n+1];
int i,j;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
if(i<j)
dp[i][j]=0;
else if(j==1)
dp[i][j]=pow(p,i-1);
else
dp[i][j]=dp[i-1][j]*j*p+dp[i-1][j-1]*(n-j+1)*p;
}
}
printf("%.4lf",dp[m][n]);
return 0;
}
有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。
3
1 3 3
2 2 2
3 1 2
#include<iostream>
#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int dp[1010][1010];
int main() {
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>dp[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dp[i-1][j]>dp[i][j-1]){
dp[i][j]+=dp[i-1][j];
}else{
dp[i][j]+=dp[i][j-1];
}
}
}
cout<<dp[n][n];
return 0;
}
状态压缩DP
搜索与图论
dfs深度优先搜索
模板:递归,结束条件,枚举,恢复现场
#include <iostream>
using namespace std;
const int N = 10;
int n;
int path[N];
void dfs(int u, int state)
{
//结束条件
if (u == n)
{
for (int i = 0; i < n; i ++ ) printf("%d ", path[i]);
puts("");
return;
}
//枚举
for (int i = 0; i < n; i ++ )
if (!(state >> i & 1))
{
//答案覆盖,恢复现场
path[u] = i + 1;
dfs(u + 1, state + (1 << i));
}
}
int main()
{
scanf("%d", &n);
//从树的第一层开始递归
dfs(0, 0);
return 0;
}
#include <iostream>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
int n;
int res;
int d[15];
bool f[15]={false};
bool dfs(int step){
if(step==n+1){
int dd[15];
for(int i=1;i<=n;i++)
dd[i]=d[i];
//dp
for(int i=1;i<=n-1;i++)
for(int j=1;j<=n-i;j++)
dd[j]+=dd[j+1];
if(dd[1]==res){
for(int i=1;i<=n;i++)
cout<<d[i]<<" ";
return true;
}
else
return false;
}
for(int i=1;i<=n;i++){
if(f[i])
continue;
d[step]=i;
f[i]=true;
if(dfs(step+1))
return true;
f[i]=false;
}
return false;
}
int main()
{
cin>>n>>res;
dfs(1);
return 0;
}
经验:bool数组为标记
string maze[110];//当作char[110][110]用
bool vis[110][110];//记录点是否经历过
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
bool in(int x,int y){//点是否在迷宫里
return 0<=x&&x<n&&0<=y&&y<m;
}
bool dfs(int x,int y){
if(maze[x][y]=='T'){//找到出口
return true;
}
vis[x][y]=1;
maze[x][y]='m';
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){//如果满足条件就退出循环
if(dfs(tx,ty)){
return true;
}
}
}
vis[x][y]=0;//不满足条件,做标记,退出循环
maze[x][y]='.';
return false;
}
抽象深度优先搜索(搜索树)
#include<iostream>
using namespace std;
int n,k,sum,ans;//n个数中选k个数的和sum
int a[40];
void dfs(int i,int cnt,int s){//当前选的哪个,已经选了几个,已经选了几个的和
if(i==n){//满足条件,记录答案
if(cnt==k&&s==sum){
ans++;
}
return;
}
dfs(i+1,cnt,s);//不选
dfs(i+1,cnt+1,s+a[i]);//选
}
int main(){
cin>>n>>k>>sum;
for(int i=0;i<n;i++){
cin>>a[i];
}
ans=0;
dfs(0,0,0);
cout<<ans<<endl;
return 0;
}
#include<iostream>
#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
vector<int> G[100003];
int dfs(int u,int fa){//参数fa表示u的父节点,用于避免u和fa之间的自环
if(u==fa)return 1;//如果u就是其父节点fa,说明找到了一个自环,返回距离为1
int dis=0;//用于记录从u出发到其子树中的最远节点的距离
for(int i=0;i<G[u].size();i++){//遍历每个儿子
dis=max(dis,dfs(G[u][i],u));//对每个子节点调用DFS,并更新dis为所有子节点中的最大值
}
return dis+G[u].size();//返回从u出发到其子树中的最远节点的距离(即子节点的数量加上最远的子节点的距离)
}
int main() {
int n;
cin>>n;
for(int i=2;i<=n;i++){
int x;
cin>>x;
G[x].push_back(i);
}
cout<<dfs(1,0);
return 0;
}
N皇后
右上左下的斜线的行加列为4
左上右下的斜线的行减列为-2
#include<iostream>
using namespace std;
int ans=0;//答案,n种放置方法
bool col[10],x1[20],x2[20];//标记数组,表示列和两条对角线
bool check(int r,int i){//对应的列和两条对角线没有被占用就可以放置
return !col[i]&&!x1[r+i]&&!x2[r-i+8];
}
void dfs(int r){
if(r==8){//完成出口
ans++;
return;
}
for(int i=0;i<8;i++){
if(check(r,i)){//第r行第i列的位置是否可以放下
col[i]=x1[r+i]=x2[r-i+8]=true;//加8是因为r-i可能为负数
dfs(r+1);
col[i]=x1[r+i]=x2[r-i+8]=false;//回溯取消标记
}
}
}
int main(){
dfs(0);
cout<<ans<<endl;
return 0;
}
剪枝策略
可行性剪枝
if(cnt>k){//可行性剪枝
return;
}
if(s>sum){
return;
}
最优性剪枝(BFS)
if(step>=ans){
return;
}
if(maze[x][y]=='T'){
ans=step;
return;
}
重复性剪枝 奇偶性剪枝
bfs广度优先搜索
char start[5][5],goal[5][5];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
map<string,int> vis;
struct Node
{
int x,y;//该结点的坐标值
long long step;//计算所需的步数
char Map[5][5];//该结点存在时,所有点的位置图
};
int bfs(int m,int n)
{
queue<Node> Q;//创建含结构体队列
Node now,next;//创建当前结点与下一个结点
now.x = m;//当前结点的x值等于起始点的x值
now.y = n;
now.step = 0;//所需步数初始为0
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++)
now.Map[i][j] = start[i][j];//当前结点的所有点的位置图初始化
}
Q.push(now);//将当前结点放入队列中
while(!Q.empty()){//若队列不为空
now = Q.front();//访问队列中队首元素
Q.pop();//删除队首元素
if(check(now)){//如果满足所需条件
return now.step;
}
for(int i=0;i<4;i++){
next.x = now.x + dx[i];//下一个结点点的定义
next.y = now.y + dy[i];
for(int k=1;k<=3;k++){
for(int j=1;j<=3;j++)
next.Map[k][j]= now.Map[k][j];//下一个结点的所有点的位置图初始化
}
if(next.x>=1 && next.x<=3 && next.y>=1 && next.y<=3){//需要满足访问下一个结点不能越界
swap(next.Map[next.x][next.y],next.Map[now.x][now.y]);///交换两个方格的位置;
if(pd(next)){//如果当前局面未出现过
next.step = now.step + 1;//所需步数加一
Q.push(next);//加下一个结点放入队列,准备访问下一个结点
}
}
}
}
return -1;
}
九宫重排 ,大胖子走迷宫
迪杰斯特拉(单源最短路)
#include<iostream>
#include <algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int INF=99999;
struct node{
int next;
int value;
};
vector<node> a[20005];
int n,e,v,u;
int dist[20005]; //The shortest path from start to i
int visit[20005]; //Record whether access
void Dijkstra(int v){
//Initialize the dist array to store the shortest distances from the source to each vertex.
fill(dist, dist + 20005, INF);
// The distance from the source point to itself is 0.
dist[v] = 0;
//Traverse all vertices.
for(int i = 0; i < n; i++){
//Initialize u as -1, which is used to store the index of the vertex with the minimum distance.
u = -1;
int minx = INF;
//In the unvisited vertices, find the vertex with the minimum distance.
for(int j = 0; j < n; j++){
if(visit[j] == 0 && dist[j] < minx){ //If the vertex has not been visited and the distance is shorter
u = j; //Update the serial number of the vertex with minimum distance
minx = dist[j];
}
}
// If the vertex with the minimum distance is -1, it means that all vertices have been visited.
if(u == -1) break;
//The found vertex will be marked as visited.
visit[u] = 1;
//Traverse all the adjacent vertices x of the vertex.
for(int i = 0; i < a[u].size(); i++){
int x = a[u][i].next;
if(visit[x] == 0 && dist[u] + a[u][i].value < dist[x]){
dist[x] = dist[u] + a[u][i].value;
}
}
}
}
int main(){
cin >> n >> e;
int last,Next,Value;
memset(visit,0,sizeof(visit));
for(int i = 0;i < e;i ++){
cin >> last >> Next >> Value;
struct node temp = {Next,Value};
a[last].push_back(temp);
}
Dijkstra(v);
for(int i = 1;i < n;i ++){
if(dist[i] != INF){
cout << dist[i] << " ";
}
}
}
常见问题
如何储存和使用题目所给数据?
二维数组(i行j列),vector容器
使用结构体并用运算符重载
进制转换
十进制转二进制
for(int i=0;i<32;i++){
cout<<i%32/16<<i%16/8<<i%8/4<<i%4/2<<i%2<<endl;
}
高精度
%.7f,double
#include <iostream>
#include <vector>
using namespace std;
vector<int> add(vector<int> &A, vector<int> &B)
{
if (A.size() < B.size()) return add(B, A);
vector<int> C;
int t = 0;
for (int i = 0; i < A.size(); i ++ )
{
t += A[i];
if (i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t) C.push_back(t);
return C;
}
int main()
{
string a, b;
vector<int> A, B;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
vector<int> C = add(A, B);
for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
cout << endl;
return 0;
}
使用一个数组A来表示一个大整数a,将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。固定格式
#include<iostream>
using namespace std;
int main() {
int n;
int ans[10000] = {0};
int len = 0;
ans[0] = 1;
cin >> n;
for (int i = 1; i <= n; i++) {
int heigher = 0;
for (int j = 0; j <= len; j++) {
int temp = i * ans[j] + heigher;
ans[j] = temp % 10;
heigher = temp / 10;
}
while (heigher > 0) {
ans[++len] = heigher % 10;
heigher /= 10;
}
}
for (int i = len; i >= 0; i--) {
cout << ans[i];
}
return 0;
}
数据结构
列表:顺序表,链表
初始化
struct ListNode {
int data;
ListNode* next; // 结构体指针
};
添加结点
void Listpushback(ListNode** pphead, int x) {
ListNode* newnode = new ListNode{ x, NULL }; // 创建一个新的节点,数据为x,下一个节点为NULL
if (*pphead == NULL) { // 如果链表为空(头节点为NULL)
*pphead = newnode; // 则新节点成为头节点
} else { // 否则,遍历到链表的尾部,将新节点添加到尾部
ListNode* tail = *pphead;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newnode; // 将尾部的next指向新节点,完成添加操作
}
}
打印输出
void Listprintf(ListNode* phead) {
ListNode* cur = phead; // 定义一个指针cur指向链表的头节点
while (cur != NULL) { // 当cur不为空时,继续循环
cout << cur->data << "->"; // 打印当前节点的数据,并输出"->"表示指向下一个节点
cur = cur->next; // 将cur指向下一个节点
}
}
测试
void test_1() {
ListNode* phead = NULL; // 初始化一个空链表,头节点为NULL
Listpushback(&phead, 1); // 在链表尾部添加数据1
Listpushback(&phead, 2); // 在链表尾部添加数据2
Listpushback(&phead, 3); // 在链表尾部添加数据3
Listprintf(phead); // 打印整个链表的数据
}
栈与队列
普通的栈
#include<iostream>
using namespace std;
struct Stack{
int data[10000];
int top=-1;
void push(int x){
top++;
if(top<10000){
data[top]=x;
}else{
top--;
cout<<"stack overflow"<<endl;
}
}
void pop(){
if(top>=0){
top--;
}
}
int topval(){
if(top>=0){
return data[top];
}
}
};
int main(){
Stack s;
for(int i=1;i<=10;i++){
s.push(i);
}
for(int i=1;i<=10;i++){
cout<<s.topval()<<" ";
s.pop();
}
return 0;
}
标准库里的栈
stack<int> sta
sta.push()
sta.pop()
sta.top()
sta.empty()
sta.size()
Hash
树
红黑树
图
稠密图用邻接矩阵
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int G[6][6];//二维邻接矩阵对应图
memset(G,0,sizeof(G));
int m;
cin>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
G[a][b]=1;//建立a到b的有向边
}
}
带权矩阵
稀疏图用邻接表
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int main(){
vector<int> G[11];
int m;
cin>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
G[a].push_back(b);//无向边
G[b].push_back(a);
}
for(int i=1;i<=10;i++){
cout<<i<<":";
for(int j=0;j<G[i].size();j++){
cout<<G[j][i]<<" ";
}
}
return 0;
}
带权表
函数调用
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
int findSuperiorWarehouse(const vector<vector<int> >& warehouses, int warehouseIndex, int dimension) {
for (int i = 0; i < warehouses.size(); ++i) {
if (i != warehouseIndex) {
bool isSuperior = true;
for (int j = 0; j < dimension; ++j) {
if (warehouses[warehouseIndex][j] >= warehouses[i][j]) {
isSuperior = false;
break;
}
}
if (isSuperior) {
return i + 1; // 仓库编号从1开始,所以返回i+1
}
}
}
return 0; // 如果没有上级仓库,则返回0
}
int main() {
int n, d;
cin >> n >> d; // 读取仓库数量和位置编码的维数
vector<vector<int> > warehouses(n, vector<int>(d));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < d; ++j) {
cin >> warehouses[i][j]; // 读取每个仓库的位置编码
}
}
for (int i = 0; i < n; ++i) {
cout << findSuperiorWarehouse(warehouses, i, d) << endl; // 输出每个仓库的上级仓库编号
}
return 0;
}