复制代码请务必修改防止查重!!!
温馨提示:增加空格或重新排版为无效修改!!
棋盘覆盖问题
#include <iostream>
#include<fstream>
#include <iomanip>
#define MAX 1025
using namespace std;
int board[MAX][MAX];
int tile=1;
void ChessBoard(int tr,int tc,int dr,int dc,int size)
{ if(size==1
) return; //递归出口
int t=tile++; //取一个L型骨,其牌号为tile
int s=size/2; //分割棋盘
//考虑左上角象限
if(dr<tr+s&&dc<tc+s
) //特殊方格在此象限中
ChessBoard(tr,tc,dr,dc,s)
;
else //此象限中无特殊方格
{ board[tr+s-1][tc+s-1]=t
; //用t号L型骨牌覆盖右下角
ChessBoard(tr,tc,tr+s-1,tc+s-1,s)
; //将右下角作为特殊方格继续处理该象限
}
//考虑右上角象限
if(dr<tr+s&&dc>=tc+s
)
ChessBoard(tr,tc+s,dr,dc,s)
; //特殊方格在此象限中
else //此象限中无特殊方格
{ board[tr+s-1][tc+s]=t
; //用t号L型骨牌覆盖左下角
ChessBoard(tr,tc+s,tr+s-1,tc+s,s)
; //将左下角作为特殊方格继续处理该象限
}
//处理左下角象限
if(dr>=tr+s&&dc<tc+s
) //特殊方格在此象限中
ChessBoard(tr+s,tc,dr,dc,s)
;
else //此象限中无特殊方格
{ board[tr+s][tc+s-1]=t
; //用t号L型骨牌覆盖右上角
ChessBoard(tr+s,tc,tr+s,tc+s-1,s)
; //将右上角作为特殊方格继续处理该象限
}
//处理右下角象限
if(dr>=tr+s&&dc>=tc+s
) //特殊方格在此象限中
ChessBoard(tr+s,tc+s,dr,dc,s)
;
else //此象限中无特殊方格
{ board[tr+s][tc+s]=t
; //用t号L型骨牌覆盖左上角
ChessBoard(tr+s,tc+s,tr+s,tc+s,s)
; //将左上角作为特殊方格继续处理该象限
}
}
int main()
{
int dr,dc,size;
int j,i;
cin>>size;
cin>>dr>>dc;
ChessBoard(0,0,dr,dc,size);
for(i=0;i<size;i++){
cout<<left;
for(j=0;j<size;j++)
{
cout<<setfill(' ')<<setw(5)<<board[i][j];
}
cout<<endl;
}
return 0;
}
快速排序
#include <iostream>
#define MAXSIZE 1000
using namespace std;
typedef struct
{
int key;
char *otherinfo;
}ElemType;
typedef struct
{
ElemType *r;
int length;
}SqList;
int Partition(SqList &L,int low,int high)
{
int pivotkey;
L.r[0]=L.r[low];
pivotkey=L.r[low].key;
while(
low<high
)
{
while(
low<high&&L.r[high].key>=pivotkey
) --high;
L.r[low]=L.r[high];
while(
low<high&&L.r[low].key<=pivotkey
) ++low;
L.r[high]=L.r[low];
}
L.r[low]=L.r[0];
return low;
}
void QSort(SqList &L,int low,int high)
{
int pivotloc;
if(low<high)
{
pivotloc= Partition(L,low,high)
;
QSort(L,low,pivotloc-1)
;
QSort(L,pivotloc+1,high)
;
}
}
void QuickSort(SqList &L)
{
QSort(L,1,L.length);
}
void Create_Sq(SqList &L)
{
int i,n;
cin>>n; //输入的值不大于 MAXSIZE
for(i=1;i<=n;i++)
{
cin>>L.r[i].key;
L.length++;
}
}
void show(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
if(i==1)
cout<<L.r[i].key;
else
cout<<" "<<L.r[i].key;
}
int main()
{
SqList L;
L.r=new ElemType[MAXSIZE+1];
L.length=0;
Create_Sq(L);
QuickSort(L);
show(L);
return 0;
}
归并排序
#include <iostream>
#define MAXSIZE 1000
using namespace std;
typedef struct
{
int key;
char *otherinfo;
}ElemType;
typedef struct
{
ElemType *r;
int length;
}SqList;
void Create_Sq(SqList &L)
{
int i,n;
cin>>n; //输入的值不大于 MAXSIZE
for(i=1;i<=n;i++)
{
cin>>L.r[i].key;
L.length++;
}
}
void show(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
if(i==1)
cout<<L.r[i].key;
else
cout<<" "<<L.r[i].key;
}
void Merge(ElemType R[],ElemType T[],int low,int mid,int high)
{
int i,j,k;
i=low; j=mid+1;k=low;
while(i<=mid&&j<=high)
{
if(R[i].key<=R[j].key) T[k++]=R[i++];
else T[k++]=R[j++];
}
while(i<=mid)
T[k++]=R[i++];
while(j<=high)
T[k++]=R[j++];
}
void MSort(ElemType R[],ElemType T[],int low,int high)
{
int mid;
ElemType *S=new ElemType[MAXSIZE];
if(low==high)
T[low]=R[low]
;
else
{
mid=(low+high)/2;
MSort(R,S,low,mid)
;
MSort(R,S,mid+1,high)
;
Merge(S,T,low,mid,high)
;
}
}
void MergeSort(SqList &L)
{
MSort(L.r,L.r,1,L.length);
}
int main()
{
SqList R;
R.r=new ElemType[MAXSIZE+1];
R.length=0;
Create_Sq(R);
MergeSort(R);
show(R);
return 0;
}
部分背包问题(贪心法)
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 51
//问题表示
int n;
double W; //限重
struct NodeType
{ int no;
double w;
double v;
double p; //p=v/w
float x;
bool operator<(const NodeType &s) const
{
return p>s.p; //按p递减排序
}
};
NodeType A[MAXN]={{0}}; //下标0不用
//求解结果表示
double V; //最大价值
bool cmp(const NodeType &a,const NodeType &b)
{
return a.no<b.no;
}
void Knap() //求解背包问题并返回总价值
{
V=0; //V初始化为0
double weight=W; //背包中能装入的余下重量
int i=1;
while (
A[i].w<=weight
)
{ A[i].x=1; //装入物品i
weight-=A[i].w
;
V+=A[i].v; //累计总价值
i++
;
}
if (weight>0) //当余下重量大于0
{ A[i].x=
weight/A[i].w
;
V+=A[i].x*A[i].v; //累计总价值
}
}
int main()
{ cin>>n>>W;
for(int i=1;i<=n;i++)
{
cin>>A[i].no>>A[i].w>>A[i].v;A[i].x=0;
}
for (int i=1;i<=n;i++) //求v/w
A[i].p=A[i].v/A[i].w;
sort(A+1,A+n+1); //排序
Knap();
sort(A+1,A+n+1,cmp);
for(int j=1;j<=n;j++)
cout<<A[j].no<<" "<<A[j].x*A[j].v<<endl;
cout<<V;
return 0;
}
最小生成树(普里姆算法)
#include <iostream>
#define MVNum 100
#define MaxInt 32767
using namespace std;
struct edge{
char adjvex;
int lowcost;
}closedge[MVNum];
typedef struct{
char vexs[MVNum];
int arcs[MVNum][MVNum];
int vexnum,arcnum;
}AMGraph;
int LocateVex(AMGraph G , char v);//实现细节隐藏
int CreateUDN(AMGraph &G);//实现细节隐藏
int Min(AMGraph G){
int i;
int index = -1;
int min = MaxInt;
for(i = 0 ; i < G.vexnum ; ++i){
if(
min > closedge[i].lowcost && closedge[i].lowcost != 0
){
min = closedge[i].lowcost;
index = i;
}
}
return index;
}
void MiniSpanTree_Prim(AMGraph G, char u){
int k , j , i;
char u0 , v0;
k =LocateVex(G, u);
for(j = 0; j < G.vexnum; ++j){
if(j != k){
closedge[j].adjvex =
u
;
closedge[j].lowcost =
G.arcs[k][j]
;
}
}
closedge[k].lowcost =
0
;
for(i = 1; i < G.vexnum; ++i){
k =
Min(G)
;
u0 = closedge[k].adjvex;
v0 = G.vexs[k];
cout << u0 << "->" << v0 << endl;
closedge[k].lowcost =
0
;
for(j = 0; j < G.vexnum; ++j)
if(G.arcs[k][j] < closedge[j].lowcost){
closedge[j].adjvex =
G.vexs[k]
;
closedge[j].lowcost =
G.arcs[k][j]
;
}
}
}
int main(){
AMGraph G;
CreateUDN(G);
char u;
cin >> u;
MiniSpanTree_Prim(G , u);
return 0;
}
求解活动安排问题(贪心法)
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 51
//问题表示
struct Action
{ int b; //活动起始时间
int e; //活动结束时间
bool operator<(const Action &s) const //重载<关系函数
{
return e<=s.e; //用于按活动结束时间递增排序
}
};
int n;
Action A[MAX];
bool flag[MAX]; //标记选择的活动
int Count=0; //选取的兼容活动个数
void solve() //求解最大兼容活动子集
{
memset(flag,0,sizeof(flag));//初始化为false
sort(A,A+n); //A[1..n]按活动结束时间递增排序
int preend=0; //前一个兼容活动的结束时间
for (int i=0;i<n;i++)
{ if (
A[i].b>=preend
)
{
flag[i]=true
;
preend=A[i].e
;
}
}
}
int main()
{ cin>>n;
for (int i=0;i<n;i++)
cin>>A[i].b>>A[i].e;
solve();
for (int i=0;i<n;i++)
if (flag[i])
{
printf("[%d,%d]\n",A[i].b,A[i].e);
Count++;
}
cout<<Count;
return 0;
}
多段图问题(动态规划法)
#include<bits/stdc++.h>
using namespace std;
const int N = 20;
const int MAX = 1000;
int arc[N][N];
int Backpath(int n);
int creatGraph();
int main()
{
int n = creatGraph( );
int pathLen = Backpath(n);
cout<<pathLen;
return 0;
}
int creatGraph()
{
int i, j, k;
int weight;
int vnum, arcnum;
cin>>vnum>>arcnum;
for (i = 0; i < vnum; i++)
for (j = 0; j < vnum; j++)
arc[i][j] = MAX;
for (k = 0; k < arcnum; k++)
{
cin>>i>>j>>weight;
arc[i][j] = weight;
}
return vnum;
}
int Backpath(int n)
{
int i, j, temp;
int cost[N];
int path[N];
for(i = 0; i < n; i++)
{
cost[i] = MAX;
path[i] = -1;
}
cost[0] = 0;
for(j = 1; j < n; j++)
{
for(i = j - 1; i >= 0; i--)
{
if (
arc[i][j] + cost[i] < cost[j]
)
{
cost[j] = arc[i][j] + cost[i]
;
path[j]
= i;
}
}
}
return
cost[n-1]
;
}
最短路径(弗洛伊德算法)
#include <iostream>
using namespace std;
#define MaxInt 32767
#define MVNum 100
typedef char VerTexType;
typedef int ArcType;
int Path[MVNum][MVNum];
int D[MVNum][MVNum];
typedef struct{
VerTexType vexs[MVNum];
ArcType arcs[MVNum][MVNum];
int vexnum,arcnum;
}AMGraph;
int LocateVex(AMGraph G , VerTexType v);//实现细节隐藏
void CreateUDN(AMGraph &G);//实现细节隐藏
void ShortestPath_Floyed(AMGraph G){
int i , j , k ;
for (i = 0; i < G.vexnum; ++i)
for(j = 0; j < G.vexnum; ++j){
D[i][j] =
G.arcs[i][j]
;
if(D[i][j] < MaxInt && i != j)
Path[i][j]=i
;
else Path [i][j] = -1;
}
for(k = 0; k < G.vexnum; ++k)
for(i = 0; i < G.vexnum; ++i)
for(j = 0; j < G.vexnum; ++j)
if(
D[i][k] + D[k][j]
< D[i][j]){
D[i][j] =
D[i][k]+D[k][j]
;
Path[i][j] =
Path[k][j]
;
}
}
void DisplayPath(AMGraph G , int begin ,int temp ){
if(Path[begin][temp] != -1){
DisplayPath(G , begin ,Path[begin][temp]);
cout << G.vexs[Path[begin][temp]] << "->";
}
}
int main(){
AMGraph G;
char start , destination;
int num_start , num_destination;
CreateUDN(G);
ShortestPath_Floyed(G);
cin >> start >> destination;
num_start = LocateVex(G , start);
num_destination = LocateVex(G , destination);
DisplayPath(G , num_start , num_destination);
cout << G.vexs[num_destination]<<endl;
cout << D[num_start][num_destination];
return 0;
}
求解图的m着色问题(回溯法)
#include <stdio.h>
#include <string.h>
#define MAXN 20 //图最多的顶点个数
int n,k,m;
int a[MAXN][MAXN];
int count=0; //全局变量,累计解个数
int x[MAXN]; //全局变量,x[i]表示顶点i的着色
bool Same(int i) //判断顶点i是否与相邻顶点存在相同的着色
{
for (int j=1;j<=n;j++)
if (
a[i][j]==1 && x[i]==x[j]
)
return false;
return true;
}
void dfs(int i) //求解图的m着色问题
{
if (i>n)
{
count++
;
}
else
{
for (int j=1;j<=m;j++)
{
x[i]=j;
if (
Same(i)
)
dfs(i+1);
x[i]=0
;
}
}
}
int main()
{
memset(a,0,sizeof(a)); //a初始化
memset(x,0,sizeof(x)); //x初始化
int x,y;
scanf("%d%d%d",&n,&k,&m); //输入n,k,m
for (int j=1;j<=k;j++)
{
scanf("%d%d",&x,&y); //输入一条边的两个顶点
a[x][y]=1; //无向图的边对称
a[y][x]=1;
}
dfs(1); //从顶点1开始搜索
if (count>0) //输出结果
printf("%d",count);
else
printf("-1");
return 0;
}
0/1背包问题(回溯法)
#include <stdio.h>
#include <string.h>
#include <iostream>
#define MAXN 20 //最多物品数
using namespace std;
int n; //物品数
int W; //限制重量
int w[MAXN]={0}; //存放物品重量,不用下标0元素
int v[MAXN]={0}; //存放物品价值,不用下标0元素
int x[MAXN]; //存放最终解
int maxv; //存放最优解的总价值
void dfs(int i,int tw,int tv,int rw,int op[]) //求解0/1背包问题
{
int j;
if (i>n) //找到一个叶子结点
{ if (
tw==W && tv>maxv
) //找到一个满足条件的更优解,保存它
{ maxv=tv;
for (
j=1;j<=n;j++
) //复制最优解
x[j]=op[j];
}
}
else //尚未找完所有物品
{ if (
tw+w[i]<=W
) //左孩子结点剪枝:满足条件时才放入第i个物品
{
op[i]=1; //选取第i个物品
dfs(
i+1,tw+w[i],tv+v[i],rw-w[i],op
);
}
op[i]=0; //不选取第i个物品,回溯
if (
tw+rw>W
) //右孩子结点剪枝
dfs(
i+1,tw,tv,rw-w[i],op
);
}
}
void dispasolution() //输出最优解
{ int i;
for (i=1;i<=n;i++)
if (x[i]==1)
printf("%d ",i);
printf("\n%d %d",W,maxv);
}
int main()
{
int i;
cin>>n>>W; //输入物体个数及背包载重量
for(int i=1;i<=n;i++)//输入各物体重量及价值
cin>>w[i]>>v[i];
int op[MAXN]; //存放临时解
memset(op,0,sizeof(op));
int rw=0;
for (int i=1;i<=n;i++)
rw+=w[i];
dfs(1,0,0,rw,op);
dispasolution();
return 0;
}
求解n皇后问题(递归回溯法)
#include <stdio.h>
#include <stdlib.h>
#define N 20 //最多皇后个数
int q[N]; //存放各皇后所在的列号,即(i,q[i])为一个皇后位置
void dispasolution(int n) //输出n皇后问题的一个解
{
for (int i=1;i<=n;i++)
printf("(%d,%d)",i,q[i]);
printf("\n");
}
bool place(int i,int j) //测试(i,j)位置能否摆放皇后
{
if (i==1) return true; //第一个皇后总是可以放置
int k=1;
while (k<i) //k=1~i-1是已放置了皇后的行
{ if ((q[k]==j) || (abs(q[k]-j)==abs(i-k)))
return false
;
k++;
}
return true
;
}
void queen(int i,int n) //放置1~i的皇后
{ if (i>n)
dispasolution(n); //所有皇后放置结束
else
{
for (int j=1;j<=n;j++) //在第i行上试探每一个列j
if (
place(i,j)
) //在第i行上找到一个合适位置(i,j)
{ q[i]=j;
queen(i+1,n)
;
}
}
}
int main()
{ int n; //n为存放实际皇后个数
scanf("%d",&n);
if (n<=20)
queen(1,n); //放置1~i的皇后
return 0;
}
0/1背包问题(回溯法)
void dfs(int i,int tw,int tv,int rw,int op[]) {
if(i > n) {
if(tw == W && tv > maxv) {
maxv = tv;
for(int j = 1; j <= n; j ++ ) x[j] = op[j];
}
} else {
if(tw + w[i] <= W) {
op[i] = 1;
dfs(i + 1, tw + w[i], tv + v[i], rw - w[i], op);
}
op[i] = 0;
if(tw + rw > W) dfs(i + 1, tw, tv, rw - w[i], op);
}
}
快速排序(分治法)
int Partition(SqList &L,int low,int high) {
L.r[0] = L.r[low];
int t = L.r[low].key;
while(low < high) {
while(low < high && L.r[high].key >= t) high --;
L.r[low] = L.r[high];
while(low < high && L.r[low].key <= t) low ++ ;
L.r[high] = L.r[low];
}
L.r[low] = L.r[0];
return low;
}
void QSort(SqList &L,int low,int high) {
if(low < high) {
int t = Partition(L, low, high);
QSort(L, low, t - 1);
QSort(L, t + 1, high);
}
}
棋盘覆盖问题(分治法)
void ChessBoard(int tr,int tc,int dr,int dc,int size) {
if(size == 1) return;
int s = size / 2;
int t = tile ++;
if(dr < tr + s && dc < tc + s) ChessBoard(tr, tc, dr, dc, s);
else {
board[tr + s - 1][tc + s - 1] = t;
ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);
}
if(dr < tr + s && dc >= tc + s) ChessBoard(tr, tc + s, dr, dc, s);
else {
board[tr + s - 1][tc + s] = t;
ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);
}
if(dr >= tr + s && dc < tc + s) ChessBoard(tr + s, tc, dr, dc, s);
else {
board[tr + s][tc + s - 1] = t;
ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);
}
if(dr >= tr + s && dc >= tc + s) ChessBoard(tr + s, tc + s, dr, dc, s);
else {
board[tr + s][tc + s] = t;
ChessBoard(tr + s, tc + s, tr + s, tc + s, s);
}
}
求解活动安排问题(贪心法)
void solve() {
sort(A, A + n);
int t = 0;
for(int i = 0; i < n; i ++ ) {
if(A[i].b >= t) {
flag[i] = true;
t = A[i].e;
}
}
}
最小生成树(克鲁斯卡尔算法)
int p[MVNum];
int find(int x) {
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
void Kruskal(AMGraph G) {
for(int i = 0; i < G.vexnum; i ++ ) p[i] = i;
for(int k = 0; k < G.arcnum; k ++ ) {
int min = MaxInt, mini = MaxInt, minj = MaxInt;
for(int i = 0; i < G.vexnum; i ++ ) {
for(int j = 0; j < G.vexnum; j ++ ) {
if(G.arcs[i][j] < min) {
min = G.arcs[i][j];
mini = i;
minj = j;
}
}
}
int pa = find(mini), pb = find(minj);
if(pa != pb) {
p[pa] = pb;
printf("%d->%d\n", mini, minj);
}
G.arcs[mini][minj] = G.arcs[minj][mini] = MaxInt;
}
}
求解最长递增子序列问题(动态规划法)
void IncreaseOrder(int a[],int dp[],int x[][N],int n) {
for(int i = 0; i < n; i ++ ) {
dp[i] = 1;
x[i][0] = a[i];
int max = 1, maxi = i;
for(int j = 0; j < i; j ++ ) {
if(a[j] < a[i] && dp[j] + 1 > max) {
max = dp[j] + 1;
maxi = j;
}
}
if(maxi != i) {
dp[i] = max;
for(int j = 0; j < max - 1; j ++ ) x[i][j] = x[maxi][j];
x[i][max - 1] = a[i];
}
}
}
最短路径(弗洛伊德算法)
void ShortestPath_Floyed(AMGraph G){
int i , j , k ;
for (i = 0; i < G.vexnum; ++i)
for(j = 0; j < G.vexnum; ++j){
D[i][j] = G.arcs[i][j];
if(D[i][j] < MaxInt && i != j) Path[i][j] = i;
else Path [i][j] = -1;
}
for(k = 0; k < G.vexnum; ++k)
for(i = 0; i < G.vexnum; ++i)
for(j = 0; j < G.vexnum; ++j)
if(D[i][k] + D[k][j] < D[i][j]) {
D[i][j] = D[i][k] + D[k][j];
Path[i][j] = Path[k][j];
}
}
求解图的m着色问题(回溯法)
void dfs(int i) {
if(i > n) count ++;
else {
for(int j = 1; j <= m; j ++ ) {
x[i] = j;
if(Same(i)) dfs(i + 1);
x[i] = 0;
}
}
}
7-1 快速排序
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int a[N];
int main(){
cin >> n;
for(int i = 0; i < n; i ++ ) cin >> a[i];
sort(a, a + n);
for(int i = 0; i < n; i ++ ) {
if(i == 0) cout << a[i];
else cout << " " << a[i];
}
return 0;
}
7-2 棋盘覆盖问题
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1050;
int tile = 1;
int dr, dc, len;
int g[N][N];
void chessBorad(int tr, int tc, int dr, int dc, int len) {
if(len == 1) return;
int t = tile ++;
int s = len / 2;
if(dr < tr + s && dc < tc + s) chessBorad(tr, tc, dr, dc, s);
else {
g[tr + s - 1][tc + s - 1] = t;
chessBorad(tr, tc, tr + s - 1, tc + s - 1, s);
}
if(dr < tr + s && dc >= tc + s) chessBorad(tr, tc + s, dr, dc, s);
else {
g[tr + s - 1][tc + s] = t;
chessBorad(tr, tc + s, tr + s - 1, tc + s, s);
}
if(dr >= tr + s && dc < tc + s) chessBorad(tr + s, tc, dr, dc, s);
else {
g[tr + s][tc + s - 1] = t;
chessBorad(tr + s, tc, tr + s, tc + s - 1, s);
}
if(dr >= tr + s && dc >= tc + s) chessBorad(tr + s, tc + s, dr, dc, s);
else {
g[tr + s][tc + s] = t;
chessBorad(tr + s, tc + s, tr + s, tc + s, s);
}
}
int main(){
cin >> len >> dr >> dc;
chessBorad(0, 0, dr, dc, len);
for(int i = 0; i < len; i ++ ) {
for(int j = 0; j < len; j ++ ) {
printf("%-5d", g[i][j]);
}
cout << endl;
}
return 0;
}
7-3 活动选择问题
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
struct T {
int l, r;
}t[N];
int n, cnt, now;
bool cmp(struct T a, struct T b) {
return a.r < b.r;
}
int main(){
cin >> n;
for(int i = 0; i < n; i ++ ) cin >> t[i].l >> t[i].r;
sort(t, t + n, cmp);
for(int i = 0; i < n; i ++ ) {
if(t[i].l >= now) {
cnt ++;
now = t[i].r;
}
}
cout << cnt;
return 0;
}
7-4 最小生成树-kruskal
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e7 + 10;
struct e {
int a, b, c;
}e[N];
int n, m, cnt;
int ans;
int p[N];
int find(int x) {
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
bool cmp(struct e a, struct e b) {
return a.c < b.c;
}
int main() {
cin >> n >> m;
for(int i = 0; i < m; i ++ ) scanf("%d %d %d", &e[i].a, &e[i].b, &e[i].c);
sort(e, e + m, cmp);
for(int i = 0; i < n; i ++ ) p[i] = i;
for(int i = 0; i < m; i ++ ) {
int pa = find(e[i].a);
int pb = find(e[i].b);
if(pa != pb) {
p[pa] = pb;
ans += e[i].c;
cnt ++;
}
if(cnt == n - 1) break;
}
cout << ans;
return 0;
}
7-5 最长公共子序列长度
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m;
char a[N], b[N];
int f[N][N];
int main(){
scanf("%s %s", a + 1, b + 1);
n = strlen(a + 1);
m = strlen(b + 1);
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= m; j ++ ) {
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
if(a[i] == b[j]) f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
}
}
cout << f[n][m];
return 0;
}
7-6 最短路径之Floyd
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
const int INF = 0x3f3f3f3f;
int n, m;
int d[N][N];
string p[N][N];
void floyd() {
for(int k = 0; k < n; k ++ ) {
for(int i = 0; i < n; i ++ ) {
for(int j = 0; j < n; j ++ ) {
if(d[i][k] + d[k][j] < d[i][j]) {
d[i][j] = d[i][k] + d[k][j];
p[i][j] = p[i][k] + p[k][j];
}
}
}
}
}
void print(int a, int b) {
if(d[a][b] > INF / 2) printf("%d->%d:-1\n", a, b);
else {
string s = p[a][b];
string str = "";
str += s[0];
for(int i = 1; i < s.size(); i ++ ) {
if(s[i] != s[i - 1]) str += s[i];
}
cout << str << ":" << d[a][b] << endl;
}
}
int main(){
cin >> n >> m;
for(int i = 0; i < n; i ++ ) {
for(int j = 0; j < n; j ++ ) {
if(i == j){
d[i][j] = 0;
p[i][j] = to_string(i) + "->" + to_string(j);
}
else d[i][j] = INF;
}
}
for(int i = 0; i < m; i ++ ) {
int a, b, c;
cin >> a >> b >> c;
d[a][b] = c;
p[a][b] = to_string(a) + "->" + to_string(b);
}
floyd();
for(int i = 0; i < 2; i ++ ) {
int a, b;
cin >> a >> b;
print(a, b);
}
int maxi = -1, maxj = -1, maxx = -INF;
for(int i = 0; i < n; i ++ ) {
for(int j = 0; j < n; j ++ ) {
if(d[i][j] > maxx && d[i][j] < INF / 2) {
maxi = i;
maxj = j;
maxx = d[i][j];
}
}
}
print(maxi, maxj);
return 0;
}
7-7 图着色问题
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510;
int n, m, k;
int p, sum;
int color[N];
int cnt[N];
struct E {
int l, r;
}e[N * N];
int main(){
cin >> n >> m >> k;
for(int i = 0; i < m; i ++ ) cin >> e[i].l >> e[i].r;
cin >> p;
while(p -- ) {
memset(cnt, 0, sizeof cnt);
bool flag = true;
sum = 0;
for(int i = 1; i <= n; i ++ ) {
cin >> color[i];
if(cnt[color[i]] == 0) {
cnt[color[i]] ++;
sum ++;
}
}
if(sum != k) flag = false;
for(int i = 0; i < m; i ++ ) {
if(color[e[i].l] == color[e[i].r]) {
flag = false;
break;
}
}
if(flag) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
7-8 0/1背包问题
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, M;
int p[N];
int w[N], v[N];
int f[N][N];
int main(){
cin >> n >> M;
for(int i = 1; i <= n; i ++ ) cin >> w[i] >> v[i];
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= M; j ++ ) {
f[i][j] = f[i - 1][j];
if(j >= w[i]) f[i][j] = max(f[i][j], f[i - 1][j - w[i]] + v[i]);
}
}
int k = 0;
for(int i = n, j = M; f[i][j] > 0 && i > 0; i -- ) {
if(f[i][j] != f[i - 1][j]) {
p[k ++] = i;
j -= w[i];
}
}
if(f[n][M] == 0) {
cout << "No" << endl << "0";
} else {
for(int i = k - 1; i >= 0; i -- ) cout << p[i] << " " ;
cout << endl << f[n][M];
}
return 0;
}