标签:als 哈夫曼 大于等于 最小值 秘书 fine ret end path
以下代码搬运自《趣学算法》实战演练
#include <iostream>
#include <algorithm>
const int N=1000005;
using namespace std;
double w[N]; //古董的重量数组
int main()
{
double c;
int n;
cout<<"请输入载重量c及古董个数n:"<<endl;
cin>>c>>n;
cout<<"请输入每个古董的重量,用空格分开: "<<endl;
for(int i=0;i<n;i++)
{
cin>>w[i]; //输入每个物品重量
}
sort(w,w+n); //按古董重量升序排序
double tmp=0.0;
int ans=0; // tmp为已装载到船上的古董重量,ans为已装载的古董个数
for(int i=0;i<n;i++)
{
tmp+=w[i];
if(tmp<=c)
ans++;
else
break;
}
cout<<"能装入的古董最大数量为Ans=";
cout<<ans<<endl;
return 0;
}
//可以输出古董编号
/**
struct antique{
int id; //古董的编号
double w; //古董的重量
}s[N];
bool cmp(antique a, antique b)//比较函数
{
return a.w < b.w; //指明按照古董重量升序排列
}
int main()
{
double c;
int n;
cout<<"请输入载重量c及古董个数n:"<<endl;
cin>>c>>n;
cout<<"请输入每个古董的重量,用空格分开: "<<endl;
for(int i=0;i<n;i++)
{
s[i].id=i+1;
cin>>s[i].w; //输入每个古董重量,用空格隔开
}
sort(s,s+n,cmp);
double tmp=0.0;
int ans =0; //ans记录已经装载的古董个数,tmp代表装载到船上的古董的重量
for(int i=0;i<n;i++)
{
tmp += s[i].w;
if(tmp<=c)
ans ++;
else
break;
}
cout<<"能装入的古董最大数量为Ans = ";
cout<<ans<<endl;
cout<<"装入的古董编号为";
for(int i=0;i<ans;i++)
{
cout<<s[i].id<<" ";
}
return 0;
}
**/
//program 2-2
#include<iostream>
#include<algorithm>
using namespace std;
const int M=1000005;
struct three{
double w;//每个宝物的重量
double v;//每个宝物的价值
double p;//性价比
}s[M];
bool cmp(three a,three b)
{
return a.p>b.p;//根据宝物的单位价值从大到小排序
}
int main()
{
int n;//n 表示有n个宝物
double m ;//m 表示毛驴的承载能力
cout<<"请输入宝物数量n及毛驴的承载能力m :"<<endl;
cin>>n>>m;
cout<<"请输入每个宝物的重量和价值,用空格分开: "<<endl;
for(int i=0;i<n;i++)
{
cin>>s[i].w>>s[i].v;
s[i].p=s[i].v/s[i].w;//每个宝物单位价值
}
sort(s,s+n,cmp);
double sum=0.0;// sum 表示贪心记录运走宝物的价值之和
for(int i=0;i<n;i++)//按照排好的顺序贪心
{
if( m>s[i].w )//如果宝物的重量小于毛驴剩下的承载能力
{
m-=s[i].w;
sum+=s[i].v;
}
else//如果宝物的重量大于毛驴剩下的承载能力
{
sum+=m*s[i].p;//部分装入
break;
}
}
cout<<"装入宝物的最大价值Maximum value="<<sum<<endl;//输出装入宝物的最大价值
return 0;
}
//program 2-3
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct Meet
{
int beg; //会议的开始时间
int end; //会议的结束时间
int num; //记录会议的编号
}meet[1000]; //会议的最大个数为1000
class setMeet{
public:
void init();
void solve();
private:
int n,ans; // n:会议总数 ans: 最大的安排会议总数
};
//读入数据
void setMeet::init()
{
int s,e;
cout <<"输入会议总数:"<<endl;
cin >> n;
int i;
cout <<"输入会议的开始时间和结束时间,以空格分开:"<<endl;
for(i=0;i<n;++i)
{
cin>>s>>e;
meet[i].beg=s;
meet[i].end=e;
meet[i].num=i+1;
}
}
bool cmp(Meet x,Meet y)
{
if (x.end == y.end)
return x.beg > y.beg;
return x.end < y.end;
}
void setMeet::solve()
{
sort(meet,meet+n,cmp); //对会议按结束时间排序
cout <<"排完序的会议时间如下:"<<endl;
int i;
cout <<"会议编号:"<<" 开始时间 "<<" 结束时间"<<endl;
for(i=0; i<n;i++)
{
cout<< " " << meet[i].num<<"\t\t"<<meet[i].beg <<"\t"<< meet[i].end << endl;
}
cout <<"-------------------------------------------------"<<endl;
cout << "选择的会议的过程:" <<endl;
cout <<" 选择第"<< meet[0].num<<"个会议" << endl;//选中了第一个会议
ans=1;
int last = meet[0].end; //记录刚刚被选中会议的结束时间
for( i = 1;i < n;++i)
{
if(meet[i].beg>=last)
{ //如果会议i开始时间大于等于最后一个选中的会议的结束时间
ans++;
last = meet[i].end;
cout <<" 选择第"<<meet[i].num<<"个会议"<<endl;
}
}
cout <<"最多可以安排" <<ans << "个会议"<<endl;
}
int main()
{
setMeet sm;
sm.init();//读入数据
sm.solve();//贪心算法求解
return 0;
}
//栈实现
#include <iostream>
#include<windows.h>
#include<stack>
using namespace std;
const int N=100; // 城市的个数可修改
const int INF=1e7; // 无穷大10000000
int map[N][N],dist[N],p[N],n,m;//n城市的个数,m为城市间路线的条数
bool flag[N]; //如果s[i]等于true,说明顶点i已经加入到集合S;否则顶点i属于集合V-S
void Dijkstra(int u)
{
for(int i=1; i<=n; i++)
{
dist[i] =map[u][i]; //初始化源点u到其他各个顶点的最短路径长度
flag[i]=false;
if(dist[i]==INF)
p[i]=-1; //源点u到该顶点的路径长度为无穷大,说明顶点i与源点u不相邻
else
p[i]=u; //说明顶点i与源点u相邻,设置顶点i的前驱p[i]=u
}
dist[u] = 0;
flag[u]=true; //初始时,集合S中只有一个元素:源点u
for(int i=1; i<=n; i++)
{
int temp = INF,t = u;
for(int j=1; j<=n; j++) //在集合V-S中寻找距离源点u最近的顶点t
if(!flag[j]&&dist[j]<temp)
{
t=j;
temp=dist[j];
}
if(t==u) return ; //找不到t,跳出循环
flag[t]= true; //否则,将t加入集合
for(int j=1;j<=n;j++)//更新与t相邻接的顶点到源点u的距离
if(!flag[j]&& map[t][j]<INF)
if(dist[j]>(dist[t]+map[t][j]))
{
dist[j]=dist[t]+map[t][j] ;
p[j]=t ;
}
}
}
void findpath(int u)
{
int x;
stack<int>s;
cout<<"源点为:"<<u<<endl;
for(int i=1;i<=n;i++)
{
x=p[i];
while(x!=-1)
{
s.push(x);
x=p[x];
}
cout<<"源点到其它各顶点最短路径为:";
while(!s.empty())
{
cout<<s.top()<<"--";
s.pop();
}
cout<<i<<";最短距离为:"<<dist[i]<<endl;
}
}
int main()
{
int u,v,w,st;
system("color 0d");
cout << "请输入城市的个数:"<<endl;cin >> n;
cout << "请输入城市之间的路线的个数:"<<endl;cin >>m;
cout << "请输入城市之间的路线以及距离:"<<endl;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
map[i][j]=INF;//初始化邻接矩阵为无穷大
}
while(m--)
{
cin >> u >> v >> w;
map[u][v] =min(map[u][v],w); //邻接矩阵储存,保留最小的距离
}
cout <<"请输入小明所在的位置:"<<endl; ;
cin >> st;
Dijkstra(st);
cout <<"小明所在的位置:"<<st<<endl;
for(int i=1;i<=n;i++)
{
cout <<"小明:"<<st<<" - "<<"要去的位置:"<<i;
if(dist[i] == INF)
cout << "sorry,无路可达"<<endl;
else
cout << " 最短距离为:"<<dist[i]<<endl;
}
findpath(st);
return 0;
}
//队列实现
#include <queue>
#include <iostream>
#include<cstring>
#include<windows.h>
using namespace std;
const int N = 100; // 城市的个数可修改
const int INF = 1e7; // 无穷大
int map[N][N],dist[N],n,m;
int flag[N];
struct Node{
int u,step;
Node(){};
Node(int a,int sp){
u=a;step=sp;
}
bool operator < (const Node& a)const{ // 重载 <
return step>a.step;
}
};
void Dijkstra(int st){
priority_queue <Node> Q; // 优先队列优化
Q.push(Node(st,0));
memset(flag,0,sizeof(flag));//初始化flag数组为0
for(int i=1;i<=n;++i)
dist[i]=INF; // 初始化所有距离为,无穷大
dist[st]=0;
while(!Q.empty())
{
Node it=Q.top();//优先队列队头元素为最小值
Q.pop();
int t=it.u;
if(flag[t])//说明已经找到了最短距离,该结点是队列里面的重复元素
continue;
flag[t]=1;
for(int i=1;i<=n;i++)
{
if(!flag[i]&&map[t][i]<INF){ // 判断与当前点有关系的点,并且自己不能到自己
if(dist[i]>dist[t]+map[t][i])
{ // 求距离当前点的每个点的最短距离,进行松弛操作
dist[i]=dist[t]+map[t][i];
Q.push(Node(i,dist[i]));// 把更新后的最短距离压入优先队列,注意:里面的元素有重复
}
}
}
}
}
int main()
{
int u,v,w,st;
system("color 0d");//设置背景及字体颜色
cout << "请输入城市的个数:"<<endl;
cin >> n;
cout << "请输入城市之间的路线的个数:"<<endl;
cin >>m;
for(int i=1;i<=n;i++)//初始化图的邻接矩阵
for(int j=1;j<=n;j++)
{
map[i][j]=INF;//初始化邻接矩阵为无穷大
}
cout << "请输入城市之间u,v的路线以及距离w:"<<endl;
while(m--)
{
cin>>u>>v>>w;
map[u][v]=min(map[u][v],w); //邻接矩阵储存,保留最小的距离
}
cout<<"请输入小明所在的位置:"<<endl; ;
cin>>st;
Dijkstra(st);
cout <<"小明所在的位置:"<<st<<endl;
for(int i=1;i<=n;i++)
{
cout <<"小明:"<<st<<"--->"<<"要去的位置:"<<i;
if(dist[i]==INF)
cout << "sorry,无路可达"<<endl;
else
cout << " 最短距离为:"<<dist[i]<<endl;
}
return 0;
}
//program 2-5
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXBIT 100
#define MAXVALUE 10000
#define MAXLEAF 30
#define MAXNODE MAXLEAF*2 -1
typedef struct
{
double weight;
int parent;
int lchild;
int rchild;
char value;
} HNodeType; /* 结点结构体 */
typedef struct
{
int bit[MAXBIT];
int start;
} HCodeType; /* 编码结构体 */
HNodeType HuffNode[MAXNODE]; /* 定义一个结点结构体数组 */
HCodeType HuffCode[MAXLEAF];/* 定义一个编码结构体数组*/
/* 构造哈夫曼树 */
void HuffmanTree (HNodeType HuffNode[MAXNODE], int n){
/* i、j: 循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,
x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/
int i, j, x1, x2;
double m1,m2;
/* 初始化存放哈夫曼树数组 HuffNode[] 中的结点 */
for (i=0; i<2*n-1;i++)
{
HuffNode[i].weight=0;//权值
HuffNode[i].parent=-1;
HuffNode[i].lchild=-1;
HuffNode[i].rchild=-1;
}
/* 输入 n 个叶子结点的权值 */
for (i=0; i<n; i++)
{
cout<<"Please input value and weight of leaf node "<<i+1<<endl;
cin>>HuffNode[i].value>>HuffNode[i].weight;
}
/* 构造 Huffman 树 */
for (i=0; i<n-1; i++)
{//执行n-1次合并
m1=m2=MAXVALUE;
/* m1、m2中存放两个无父结点且结点权值最小的两个结点 */
x1=x2=0;
/* 找出所有结点中权值最小、无父结点的两个结点,并合并之为一棵二叉树 */
for (j=0;j<n+i;j++)
{
if (HuffNode[j].weight<m1&&HuffNode[j].parent==-1)
{
m2 = m1;
x2 = x1;
m1 = HuffNode[j].weight;
x1 = j;
}
else if (HuffNode[j].weight < m2 && HuffNode[j].parent==-1)
{
m2=HuffNode[j].weight;
x2=j;
}
}
/* 设置找到的两个子结点 x1、x2 的父结点信息 */
HuffNode[x1].parent = n+i;
HuffNode[x2].parent = n+i;
HuffNode[n+i].weight = m1+m2;
HuffNode[n+i].lchild = x1;
HuffNode[n+i].rchild = x2;
cout<<"x1.weight and x2.weight in round "<<i+1<<"\t"<<HuffNode[x1].weight<<"\t"<<HuffNode[x2].weight<<endl; /* 用于测试 */
}
}
/* 哈夫曼树编码 */
void HuffmanCode(HCodeType HuffCode[MAXLEAF], int n){
HCodeType cd; /* 定义一个临时变量来存放求解编码时的信息 */
int i,j,c,p;
for(i=0;i<n;i++)
{
cd.start=n-1;
c=i;
p=HuffNode[c].parent;
while(p!=-1)
{
if(HuffNode[p].lchild==c)
cd.bit[cd.start]=0;
else
cd.bit[cd.start]=1;
cd.start--; /*前移一位 */
c=p;
p=HuffNode[c].parent; /* 设置下一循环条件 */
}
/* 把叶子结点的编码信息从临时编码cd中复制出来,放入编码结构体数组 */
for (j=cd.start+1; j<n; j++)
HuffCode[i].bit[j]=cd.bit[j];
HuffCode[i].start=cd.start;
}
}
int main()
{
int i,j,n;
cout<<"Please input n:"<<endl;
cin>>n;
HuffmanTree(HuffNode,n); //构造哈夫曼树
HuffmanCode(HuffCode,n); // 哈夫曼树编码
//输出已保存好的所有存在编码的哈夫曼编码
for(i=0;i<n;i++)
{
cout<<HuffNode[i].value<<": Huffman code is: ";
for(j=HuffCode[i].start+1;j<n;j++)
cout<<HuffCode[i].bit[j];
cout<<endl;
}
return 0;
}
//program 2-7
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100;
int nodeset[N];
int n, m;
struct Edge {
int u;
int v;
int w;
}e[N*N];
bool comp(Edge x, Edge y) {
return x.w < y.w;
}
void Init(int n)
{
for(int i = 1; i <= n; i++)
nodeset[i] = i;
}
int Merge(int a, int b)
{
int p = nodeset[a];
int q = nodeset[b];
if(p==q) return 0;
for(int i=1;i<=n;i++)//检查所有结点,把集合号是q的改为p
{
if(nodeset[i]==q)
nodeset[i] = p;//a的集合号赋值给b集合号
}
return 1;
}
int Kruskal(int n)
{
int ans = 0;
for(int i=0;i<m;i++)
if(Merge(e[i].u, e[i].v))
{
ans += e[i].w;
n--;
if(n==1)
return ans;
}
return 0;
}
int main() {
cout <<"输入结点数n和边数m:"<<endl;
cin >> n >> m;
Init(n);
cout <<"输入结点数u,v和边值w:"<<endl;
for(int i=1;i<=m;i++)
cin >> e[i].u>> e[i].v >>e[i].w;
sort(e, e+m, comp);
int ans = Kruskal(n);
cout << "最小的花费是:" << ans << endl;
return 0;
}
//program 2-7-1
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100;
int father[N];
int n, m;
struct Edge {
int u;
int v;
int w;
}e[N*N];
bool comp(Edge x, Edge y) {
return x.w < y.w;
}
void Init(int n)
{
for(int i = 1; i <= n; i++)
father[i] = i;
}
int Find(int x)
{
if(x != father[x])
father[x] = Find(father[x]);
return father[x];
}
int Merge(int a, int b)
{
int p = Find(a);
int q = Find(b);
if(p==q) return 0;
if(p > q)
father[p] = q;//小的赋值给大的集合号
else
father[q] = p;
return 1;
}
int Kruskal(int n)
{
int ans = 0;
for(int i=0;i<m;i++)
if(Merge(e[i].u, e[i].v))
{
ans += e[i].w;
n--;
if(n==1)
return ans;
}
return 0;
}
int main() {
cout <<"输入结点数n和边数m:"<<endl;
cin >> n >> m;
Init(n);
cout <<"输入结点数u,v和边值w:"<<endl;
for(int i=1;i<=m;i++)
cin>>e[i].u>>e[i].v>>e[i].w;
sort(e, e+m, comp);
int ans = Kruskal(n);
cout << "最小的花费是:" << ans << endl;
return 0;
}
标签:als 哈夫曼 大于等于 最小值 秘书 fine ret end path
原文地址:https://www.cnblogs.com/self-confidence/p/13603491.html